在 PHP 中加密就像 javascript CryptoJS

encrypt in PHP just like javascript CryptoJS

我有 javascript 加密并给出字符串。
但我必须通过 PHP 来做到这一点。
我尝试过的方法给我的结果不同于 javascript.

<script src="https://cdnjs.cloudflare.com/ajax/libs/crypto-js/4.0.0/crypto-js.min.js" 
            integrity="sha512-nOQuvD9nKirvxDdvQ9OMqe2dgapbPB7vYAMrzJihw5m+aNcf0dX53m6YxM4LgA9u8e9eg9QX+/+mPu8kCNpV2A==" crossorigin="anonymous"></script>

var txt="This text will be encrypted.";
var key = CryptoJS.enc.Hex.parse('0123456789abcdef0123456789abcdef');
var iv  = CryptoJS.enc.Hex.parse('abcdef9876543210abcdef9876543210');
var encrypted = CryptoJS.AES.encrypt((txt), key, { iv: iv });
var encrypted_data = encrypted.ciphertext.toString(CryptoJS.enc.Base64);
alert(encrypted_data);

我得到输出:
2X/btHgrMBhNlgD8oKNO9rzqCg+RSydprVKmpbYY+j0=

在PHP

<?php
$plaintext="This text will be encrypted.";
$key = pack("H*", "0123456789abcdef0123456789abcdef");
$iv =  pack("H*", "abcdef9876543210abcdef9876543210");
    
$ciphertext = mcrypt_encrypt(MCRYPT_RIJNDAEL_128, $key, $plaintext, MCRYPT_MODE_CBC, $iv);
$ciphertext_base64 = base64_encode($ciphertext);
echo $ciphertext_base64;
?>

我得到输出:
2X/btHgrMBhNlgD8oKNO9nJyd4xC4VTLGxnnrzGim+U=

我希望输出与 javascript 中的输出相同。
我发现开头的 21 个字符 匹配,但字符串的其余部分不匹配。
我缺少什么吗?

这是由于不同的填充。 CryptoJS 使用 PKCS#7,mcrypt 应用零填充。

您应该替换 PHP 端的 mcrypt,因为它已被弃用(第 here 节)。另一种选择是 PHP/OpenSSL,它默认使用 PKCS#7。

产生相同密文的 PHP/OpenSSL 的解是:

<?php
$plaintext="This text will be encrypted.";
$key = hex2bin("0123456789abcdef0123456789abcdef");
$iv =  hex2bin("abcdef9876543210abcdef9876543210");
    
$ciphertext_base64 = openssl_encrypt($plaintext, "aes-128-cbc", $key, 0, $iv);
echo $ciphertext_base64; // 2X/btHgrMBhNlgD8oKNO9rzqCg+RSydprVKmpbYY+j0=
?>