使用 CryptoJS 加密并使用 php 解密:IV 有什么用?

Encrypting with CryptoJS and decrypt with php: What is the use of the IV?

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

我的CryptoJS加密代码:

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

您正在使用需要 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 并且开发人员不更改代码,就绝对安全。