![](/img/trans.png)
[英]Issue encrypting with PHP (openssl_encrypt), then decrypting with JS (CryptoJS)
[英]Encrypting with PHP; decrypting with CryptoJS
我在使用用PHP加密的CryptoJS解密数据时遇到了一些麻烦。 也许有人可以向我建议我要去哪里错了?
我正在加密如下:
解密时,我也这样做:
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.