我正在尝试使用 crypto-js 加密某些内容并使用 AES 类型的加密。
我遇到的问题是每次加密时我的加密值都不一样
在这个简单的例子中,我运行相同的加密 5 次不同的时间,我得到 5 个不同的结果。这是怎么回事?
任务.js
var AES = require('crypto-js/aes');
var key = "abc123";
var secret = "encryptThisWord";
console.log(AES.encrypt(secret, key).toString());
console.log(AES.encrypt(secret, key).toString());
console.log(AES.encrypt(secret, key).toString());
console.log(AES.encrypt(secret, key).toString());
console.log(AES.encrypt(secret, key).toString());
检查
AES.encrypt(secret, key)
的内容 - 它是一个具有多个字段的对象,iv
和salt
特别感兴趣(jsFiddle)。
每次运行
AES.encrypt
crypto-js 时都会选择新的 IV 和新的 salt(顺便说一句,您可以提供自己的值)。 Random IV 意味着即使使用相同的密钥,输出也会不同,而 random salt 意味着实际的加密密钥也不同,因为它是从密码短语和 salt 派生的。
你可能(其实应该)问,为什么加密密钥和IV都不同,前十个Base64输出字符是一样的?这是因为在加密结果上调用
toString()
会将其转换为“OpenSSL 兼容字符串”,这基本上是 Base64("Salted__" + salt + ciphertext)
,其中 "Salted__"
是常量前缀,当然,它在 Base64 输出中引导相同的前缀。
我遇到了同样的问题。这仅仅是因为我们不知道算法的工作原理。简单的说就是每次调用encrypt方法的key和IV都不一样,就像上面的回答说的那样
确保每次迭代的值完全相同——可以参考这个答案https://stackoverflow.com/a/47096284/4098272
或者,您可以使用 SHA3 函数并比较两个哈希值。
我发现了问题,下面的代码有例子
var message = "Data to be encrypted";
var password = "H02u72V6fznKpcvP9ARHFqkQRlGP9om8";
function encrypt (msg, pass) {
const key = pass;
const keyutf = CryptoJS.enc.Utf8.parse(key);
const iv = CryptoJS.enc.Utf8.parse('678025308de70905');
const enc = CryptoJS.AES.encrypt(msg, keyutf, { iv: iv });
const encStr = enc.toString();
var transitmessage = enc.toString();
return transitmessage;
}
function decrypt (transitmessage, pass) {
const keyutf = CryptoJS.enc.Utf8.parse(pass);
const iv = CryptoJS.enc.Utf8.parse('678025308de70905');
const dec = CryptoJS.AES.decrypt(
{ ciphertext: CryptoJS.enc.Base64.parse(transitmessage) },
keyutf,
{
iv: iv
});
const decStr = CryptoJS.enc.Utf8.stringify(dec)
console.log('decStr', decStr);
return decStr;
}
var encrypted = encrypt(message, password);
var decrypted = decrypt(encrypted, password);