使用CryptoJS使用密码进行AES解密会返回空值

时间:2015-09-08 18:54:15

标签: 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控制台中没有触发错误。

我的问题

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

3 个答案:

答案 0 :(得分:6)

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

使用时

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

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

当您强制将encrypted转换为字符串(例如将其添加到localStorage)时,它将转换为包含salt的OpenSSL兼容字符串编码。为了再次解密,你不需要自己处理密钥,IV或盐,因为CryptoJS会自动为你解决这个问题:

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

请记住,decryptedWordArray对象,当您强制将其转换为字符串时,默认情况下会将内容编码为十六进制。如果您不想要,那么您需要自己指定编码,如UTF-8。

由于某些原因(例如错误的密钥,错误的密文或错误的编码),解密失败时通常会返回空白值。 CryptoJS不会抛出自定义错误消息,但会尝试继续,因为您应该知道自己在做什么。

完整代码:

&#13;
&#13;
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;
}
&#13;
<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">
&#13;
&#13;
&#13;

答案 1 :(得分:0)

我厌倦了通过将脚本放在try-catch中来调试代码,看起来像document.getElementById返回undefined。这是因为在创建元素之前调用了该方法。以下步骤使这项工作:

目:

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);

function setComponents() {
    try {
        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);
            alert(encrypted);
        };
    } catch(e) {
        alert(e);
    }
}

体:

<body onload="setComponents()">
<div id="decrypted">Please wait...</div>
Insert new note:<input type="text" id="new_note"/><input type="button" id="enc_button" value="Save"/>
</body>

答案 2 :(得分:-1)

您可以只检查源代码...有示例。
使其通过密码生成密钥,iv和盐的最简单方法,
CryptoJS.AES.encrypt(“黎明时发动攻击!”,“密码”)的正常方式
但是您可以使用以下示例来设置参数之前

CryptoJS.algo.AES.keySize=32
CryptoJS.algo.AES.blockSize=8
CryptoJS.algo.AES.ivSize=16
CryptoJS.algo.EvpKDF.cfg.iterations=100
CryptoJS.algo.EvpKDF.cfg.keySize=32

等等等