我对尝试使用 CryptoJS 加密某些东西浪费了很多时间感到非常沮丧,一段时间后,我意识到每次使用相同的输入加密结果都是不同的!这怎么可能?
这是我的代码,您可以检查它是否正确: https://jsfiddle.net/z5dg623q/1/
<script>
function encrypt() {
document.getElementById("stringOutput").value = CryptoJS.AES.encrypt("lorem ipsum", "hAPgT2mj0ZzD1epO").toString();
}
</script>
<textarea id="stringOutput" cols="100" rows="10"></textarea>
<button type="button" onClick="encrypt()">Encrypt that!</button>
谁能帮帮我?
最佳答案
当您将两个字符串传递给 CryptoJS.<Cipher>.encrypt()
时你告诉 CryptoJS 使用基于密码的加密。它将假定第一个字符串是 UTF-8 编码数据,第二个字符串是将通过 MD5 发送以获得 256 位 key 和 128 位 IV 的密码。这是由所谓的 EvpKDF(参见 1 和 2)使用随机盐(参见here)完成的。
这意味着在每次调用中,代码都会生成一个新的随机盐,然后每次都使用该盐派生出不同的 key 和 IV,从而每次都会产生不同的密文。此属性称为语义安全,可防止例如攻击者仅通过查看密文来确定明文是否相等。这有时是一个重要的安全属性。
当您调用 toString()
时在 encrypt()
上结果,它将密文序列化为包含盐的 OpenSSL 兼容格式。所以你只需要密码和这个字符串来解密它。
当您尝试解密它时,密文中的盐和您的密码用于派生用于加密的相同 key 和 IV。因此它可以恢复原来的明文。如果使用了错误的密码,结果要么是空的,要么是乱码。
关于javascript - 每次使用 CryptoJS 加密相同的文本时,输出都不同,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31836042/