这是我的示例代码
const CryptoJS = require('crypto-js')
const plaintext = "hello world"
const passphrase = "my_passphrase"
const encrypted = CryptoJS.AES.encrypt(plaintext, passphrase)
console.log("plaintext =", plaintext)
console.log("passphrase =", passphrase)
console.log("-----------------------------------------------------------")
console.log("key =", encrypted.key+'')
console.log("iv =", encrypted.iv+'')
console.log("salt =", encrypted.salt+'')
console.log("encrypted =", encrypted+'')
console.log("-----------------------------------------------------------")
var decrypted = CryptoJS.AES.decrypt(encrypted.toString(), passphrase);
console.log("decrypted =", decrypted.toString(CryptoJS.enc.Utf8))
输出如下:
plaintext = hello world
passphrase = my_passphrase
-----------------------------------------------------------
key = 7bb8ed7c0c9ad5b714a57073068f441dfbf032173e60bf61deea2f9a5ea2ad3a
iv = 72b8e7e60fbcf1328fd1994ea2cc7f06
salt = 03a04d2d438b4cac
encrypted = U2FsdGVkX18DoE0tQ4tMrKBbK/veZm1k0vGmFxl6sow=
-----------------------------------------------------------
decrypted = hello world
据我所知,从输出中可以看到
crypto-js
在内部加密过程中自动从密码短语中派生出带有随机盐和随机IV值的实际密钥,然后使用派生的密钥来加密明文。
我的问题是,既然 salt 和 IV 是随机生成的,那么为什么解密函数可以使用唯一的密钥密码导出相同的 AES 密钥?难道是加密数据中嵌入的盐和 IV 吗?如果是的话,加不加盐并不重要,对吧?
是的,对,但是我会把这些问题总结为两点答案,希望你能解释一下
第一个,当加密密码时,CryptoJS 生成随机盐和初始化向量(IV)。这些用于导出加密密钥。然后将盐、IV 和加密消息组合成最终的密文。
在第二个例子中,当解密密码时,CryptoJS从密文中提取salt和IV,并将它们与密码一起使用来派生原始加密密钥。然后使用该密钥将密文的其余部分解密回原始明文。