javascript - 使用 CryptoJS 使用密码进行 AES 解密返回空白值

标签 javascript encryption cryptography cryptojs

场景

我有以下代码:

<script src="http://crypto-js.googlecode.com/svn/tags/3.1.2/build/rollups/aes.js"></script>
<div id="decrypted">Please wait...</div>
Insert new note:<input type="text" id="new_note"><input type="button" id="enc_button" value="Save">
<script>
    var password = "testpassword";
    var encrypted_text = localStorage.getItem("encrypted");
    var rawData = atob(encrypted_text);
    var iv = rawData.substring(0,16);
    var crypttext = rawData.substring(16);
    var plaintextArray = CryptoJS.AES.decrypt(
      { ciphertext: CryptoJS.enc.Latin1.parse(crypttext) },
      CryptoJS.enc.Hex.parse(password),
      { iv: CryptoJS.enc.Latin1.parse(iv) }
    );
    var decrypted = CryptoJS.enc.Latin1.stringify(plaintextArray);
    document.getElementById("decrypted").innerHTML = decrypted;
    document.getElementById("enc_button").onclick = function(){
    	var text = document.getElementById("new_note").value;
    	var encrypted = CryptoJS.AES.encrypt(text, password);
    	localStorage.setItem("encrypted",encrypted);
    }
</script>

我的代码应该做什么

使用 CryptoJS 使用 AES 加密字符串;解密保存在本地存储中的加密文本并将结果显示在div中

什么不起作用

虽然字符串似乎已加密,但变量 decrypt 是空的。 chrome 控制台中没有触发任何错误。

我的问题

如何成功加密和解密我的文本?

最佳答案

CryptoJS 有两种稍微不同的加密/解密类型。

当你使用

var encrypted = CryptoJS.AES.encrypt(text, password);

那么您使用的是基于密码的加密,这与基于纯 key /IV 的加密不同。这意味着密码和随机生成的盐通过一次 MD5 调用运行,以生成用于实际加密的 key 和 IV。这是一种与 OpenSSL 兼容的加密方式。 encrypted 对象存储用于生成 key 和 IV 的随机盐。

当您强制将 encrypted 转换为字符串(例如将其添加到 localStorage)时,它会被转换为包含盐的 OpenSSL 兼容字符串编码。为了再次解密,你不需要自己弄乱 key 、IV 或加盐,因为 CryptoJS 会自动为你做这些:

var decrypted = CryptoJS.AES.decrypt(encrypted, password);

请记住,decrypted 是一个WordArray 对象,当您强制将其转换为字符串时,默认情况下会将内容编码为十六进制。如果您不想这样,则需要自己指定编码,例如 UTF-8。

由于 key 错误、密文错误或编码错误等原因导致解密失败时,通常会返回空白值。 CryptoJS 不会抛出自定义错误消息,但会尝试继续,因为您应该知道自己在做什么。

完整代码:

var password = "testpassword";

document.getElementById("enc_button").onclick = function(){
  var text = document.getElementById("new_note").value;
  
  var encrypted = CryptoJS.AES.encrypt(text, password);
  encrypted = encrypted.toString();
  
  var decrypted = CryptoJS.AES.decrypt(encrypted, password);
  decrypted = decrypted.toString(CryptoJS.enc.Utf8)
  
  document.getElementById("decrypted").innerHTML = decrypted;
}
<script src="https://cdn.rawgit.com/CryptoStore/crypto-js/3.1.2/build/rollups/aes.js"></script>
<div id="decrypted">Please wait...</div>
Insert new note:<input type="text" id="new_note"><input type="button" id="enc_button" value="Encrypt & Decrypt">

关于javascript - 使用 CryptoJS 使用密码进行 AES 解密返回空白值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32465217/

相关文章:

javascript - 绑定(bind)禁用的文本框

c++ - 如果语句不工作,输入无法识别(C++)

PHP 错误 : The Encrypt library requires the Mcrypt extension in codeigniter

java - URLClassLoader - 使用加密的 Jar

c - EVP_PKEY_sign 和 EVP_DigestSignInit 之间的区别?

javascript - React Native onEndReached 总是在渲染第一行时触发

JavaScript,创建带有链接的 div,然后通过单击所述 div 删除

PHPExcel : generating error due to php output?

ruby - 使用 Ruby OpenSSL 库时公钥无效

c# - Ruby 中的 SHA256 Base64 哈希