Crypto JS AES-128密码 - 等效的Javascript代码

问题描述:

我有以下用于创建AES-128密码的Java代码,其中密钥和iv都基于相同的密码短语。Crypto JS AES-128密码 - 等效的Javascript代码

Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding"); 
byte[] keyBytes = new byte[16]; 
byte[] b = passphare.getBytes("UTF-8"); 
int len = b.length; 
if (len > keyBytes.length) { 
    len = keyBytes.length; 
} 

System.arraycopy(b, 0, keyBytes, 0, len); 
SecretKeySpec keySpec = new SecretKeySpec(keyBytes, "AES"); 
IvParameterSpec ivSpec = new IvParameterSpec(keyBytes); 
cipher.init(opmode, keySpec, ivSpec); 

cipher.doFinal(textToEncrypt.getBytes("UTF-8")); 

我试图在JavaScript中使用相同的方法使用CryptoJS生成相同的密码,但没有成功。你能帮我么?

+0

你能提供一个简短的样本输入和输出吗?这将使编写和测试等效的cryptojs版本变得更加容易。另外,你可以添加你目前尽力而为的cryptojs尝试吗? – tucuxi

+0

是的,当然!这是我到目前为止尝试http://jsfiddle.net/jonaix/hgAZM/ –

+0

仅供参考,这是不安全的。您直接将密码转换为字节并将其用作密钥。您应该使用密码来使用基于密码的密钥派生函数(如PBKDF或bcrypt或scrypt)来生成安全密钥。你的IV也不是随机的,这是不安全的。请参阅crypto.stackexchange.com。 – Chloe

从OP的评论引述的jsfiddle:

var salt = CryptoJS.lib.WordArray.random(128/8); 
// Key and iv should be based on the same value. In this example "1111" 
var key = CryptoJS.PBKDF2("1111", salt, { keySize: 128/32 }); 
var iv = key; // Not sure what should be here!! 

您是从随机盐生成密钥(见第一行),并使用相同的密钥初始化向量...但你期待不变的结果? (如预期的那样,结果在每个调用中改变)。

解决它使用完全相同的字节keyiv从Java代码SecretKeySpecIvParameterSpec(你可以查询使用其getEncoded()方法)使用。我不知道AES SecretKeySpec是否使用PBKDF2或其他密钥派生函数 - 但它应该很容易测试。找到一个匹配并坚持下去的人。请注意CryptoJS中的默认填充是PKCS7(请参阅关于“块模式和填充”的the docs);这可能与您在第一行Java代码中指定的PKCS5有很大不同。