简体   繁体   English

用PHP加密; 用CryptoJS解密

[英]Encrypting with PHP; decrypting with CryptoJS

I am having some trouble decrypting data using CryptoJS that was encrypted in PHP. 我在使用用PHP加密的CryptoJS解密数据时遇到了一些麻烦。 Maybe somebody can advise me on where I am going wrong? 也许有人可以向我建议我要去哪里错了?

I am encrypting as follows: 我正在加密如下:

  1. Get hashed password 获取哈希密码
  2. Take substring of (0,16) as the key 以(0,16)的子字符串为键
  3. Encrypt (MCRYPT_RIJNDAEL_128) 加密(MCRYPT_RIJNDAEL_128)
  4. Encode ciphertext as base64 将密文编码为base64

When decrypting I do the same: 解密时,我也这样做:

  1. Get hashed password 获取哈希密码
  2. Take substring of (0,16) as the key 以(0,16)的子字符串为键
  3. Base64 decode the ciphertext Base64解码密文
  4. Decrypt 解密

PHP: 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: 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;
    }

The CryptoJS decrypt function expects an object that contains a WordArray and not the WordArray itself, so you need to use: CryptoJS decrypt函数需要一个包含WordArray而不包含WordArray本身的对象,因此您需要使用:

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

You also need to pass the options to the decrypt function. 您还需要将选项传递给decrypt函数。 Otherwise, CryptoJS won't know that you wanted to use ECB mode. 否则,CryptoJS不会知道您要使用ECB模式。


Security 安全

Don't use ECB mode! 不要使用ECB模式! It's not semantically secure. 这在语义上是不安全的。 You should at the very least use CBC mode with a random IV. 您至少应使用随机IV的CBC模式。 The IV doesn't need to be secret, so you can simply prepend it to the ciphertext. IV不需要是秘密的,因此您可以简单地将其前缀为密文。

Then you should authenticate your ciphertexts. 然后,您应该验证您的密文。 This can be done with authenticated modes like GCM or EAX, but they are not provided by mcrypt or CryptoJS. 可以使用GCM或EAX之类的经过身份验证的模式来完成此操作,但是mcrypt或CryptoJS不提供它们。 The next best thing is to use an encrypt-then-MAC scheme where you use a strong keyed hash function like HMAC-SHA256 over the ciphertext to make it infeasible for an attacker to change ciphertexts without you knowing it. 第二个最好的方法是使用先加密后再加密(multiple-then-MAC)方案,在该方案中,您会对密文使用诸如HMAC-SHA256之类的强键哈希函数,以使攻击者在不知道的情况下无法更改密文。

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

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

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