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生成相同的密码,但没有成功。你能帮我么?
答
从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!!
您是从随机盐生成密钥(见第一行),并使用相同的密钥初始化向量...但你期待不变的结果? (如预期的那样,结果在每个调用中改变)。
解决它使用完全相同的字节key
和iv
从Java代码SecretKeySpec
和IvParameterSpec
(你可以查询使用其getEncoded()
方法)使用。我不知道AES SecretKeySpec是否使用PBKDF2或其他密钥派生函数 - 但它应该很容易测试。找到一个匹配并坚持下去的人。请注意CryptoJS中的默认填充是PKCS7(请参阅关于“块模式和填充”的the docs);这可能与您在第一行Java代码中指定的PKCS5有很大不同。
你能提供一个简短的样本输入和输出吗?这将使编写和测试等效的cryptojs版本变得更加容易。另外,你可以添加你目前尽力而为的cryptojs尝试吗? – tucuxi
是的,当然!这是我到目前为止尝试http://jsfiddle.net/jonaix/hgAZM/ –
仅供参考,这是不安全的。您直接将密码转换为字节并将其用作密钥。您应该使用密码来使用基于密码的密钥派生函数(如PBKDF或bcrypt或scrypt)来生成安全密钥。你的IV也不是随机的,这是不安全的。请参阅crypto.stackexchange.com。 – Chloe