使用CryptoJS加密并使用php解密:IV的用途是什么?

时间:2015-07-27 10:25:21

标签: javascript php encryption cryptojs initialization-vector

我正在寻找一种方法,在CryptoJS中加密密码,然后在php中解密。我查看过有关同一主题的其他帖子,但我需要有人来解释所有这些IV和关键内容。

我的CryptoJS加密代码:

password = document.getElementById("usrp").value;
password = CryptoJS.AES.encrypt(password, <?php echo '"'.$_SESSION['adk'].'"'; ?>);

1 个答案:

答案 0 :(得分:2)

IV

您正在使用需要IV的CBC操作模式。如果您对所有密文使用静态IV,那么您将错过加密的重要属性,即语义安全性。如果您使用相同的IV,攻击者可能会观察您的密文并确定您是否使用相同的密钥发送了相同的明文,因为密文将是相同的。

为防止这种情况发生,您可以为每次加密生成随机IV。 IV不一定要保密,但必须是不可预测的。由于它不必是秘密的,您可以简单地将其添加到密文并在解密之前将其切掉,或者以结构化方式发送它。您需要在解密期间使用IV。否则,第一个块将与原始明文不同。

请记住,CryptoJS'WordArray.random()在内部使用Math.random(),这不是加密安全的。最好使用更好的随机源。对于使用WebCrypto API的半现代浏览器,您可以使用此替换功能从该函数的my project替换:

(function(C){
    var WordArray = C.lib.WordArray;
    var crypto = window.crypto;
    var TypedArray = Int32Array;
    if (TypedArray && crypto && crypto.getRandomValues) {
        WordArray.random = function(nBytes){
            var array = new TypedArray(Math.ceil(nBytes / 4));
            crypto.getRandomValues(array);
            return new WordArray.init(
                    [].map.call(array, function(word){
                        return word
                    }),
                    nBytes
            );
        };
    } else {
        console.log("No cryptographically secure randomness source available");
    }
})(CryptoJS);

并像这样使用它:

var iv = CryptoJS.lib.WordArray.random(128/8);

关键

关键是棘手的,因为它需要保密。基本方法是:

让用户键入也存在于服务器上的密码,并通过密码从密码中导出密钥,例如使用CryptoJS也提供的PBKDF2。 只要您使用TLS并且开发人员不更改代码,就会非常安全。