繁体   English   中英

用PHP加密; 用CryptoJS解密

[英]Encrypting with PHP; decrypting with CryptoJS

我在使用用PHP加密的CryptoJS解密数据时遇到了一些麻烦。 也许有人可以向我建议我要去哪里错了?

我正在加密如下:

  1. 获取哈希密码
  2. 以(0,16)的子字符串为键
  3. 加密(MCRYPT_RIJNDAEL_128)
  4. 将密文编码为base64

解密时,我也这样做:

  1. 获取哈希密码
  2. 以(0,16)的子字符串为键
  3. Base64解码密文
  4. 解密

PHP:

public function encrypt($input, $key) {
    $size = mcrypt_get_block_size(MCRYPT_RIJNDAEL_128, MCRYPT_MODE_ECB);
    $input = $this->_pkcs5_pad($input, $size);
    $td = mcrypt_module_open(MCRYPT_RIJNDAEL_128, '', MCRYPT_MODE_ECB, '');
    $iv = mcrypt_create_iv (mcrypt_enc_get_iv_size($td), MCRYPT_RAND);
    mcrypt_generic_init($td, $key, $iv);
    $data = mcrypt_generic($td, $input);
    mcrypt_generic_deinit($td);
    mcrypt_module_close($td);
    $data = base64_encode($data);
    return $data;
}

JavaScript:

function decrypt(ciphertext, hashedPsw) {
        var key =  hashedPsw.substring(0, 16);

        var key = CryptoJS.enc.Hex.parse(key);

        var options = { mode: CryptoJS.mode.ECB, padding: CryptoJS.pad.Pkcs7, keySize:128 / 32 };

        ciphertext = CryptoJS.enc.Base64.parse(ciphertext);
        var decrypted = CryptoJS.AES.decrypt(ciphertext, key);
        return decrypted;
    }

CryptoJS decrypt函数需要一个包含WordArray而不包含WordArray本身的对象,因此您需要使用:

var decrypted = CryptoJS.AES.decrypt({ ciphertext: ciphertext }, key, options);

您还需要将选项传递给decrypt函数。 否则,CryptoJS不会知道您要使用ECB模式。


安全

不要使用ECB模式! 这在语义上是不安全的。 您至少应使用随机IV的CBC模式。 IV不需要是秘密的,因此您可以简单地将其前缀为密文。

然后,您应该验证您的密文。 可以使用GCM或EAX之类的经过身份验证的模式来完成此操作,但是mcrypt或CryptoJS不提供它们。 第二个最好的方法是使用先加密后再加密(multiple-then-MAC)方案,在该方案中,您会对密文使用诸如HMAC-SHA256之类的强键哈希函数,以使攻击者在不知道的情况下无法更改密文。

我刚刚在上一个线程中找到了答案:原来,问题出在关键编码上。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM