PHP 中没有 IV 的 AES 加密和 JS 给出不同的结果

AES encryption without IV in PHP and JS gives different result

我在PHP中有下一个代码:

$plain = 'some string to encode';
$key = '01234567891234567890123456789012';
$cipherSuite = 'aes-128-cbc';
$iv = null; // I have to use null, I know it's not safe
$result = @openssl_encrypt($plain, $cipherSuite, $key, null, $iv); // Suppress warning of an empty IV
dd($result); // result is 9VK02Mt8IaS+Bng8SbqhCVXUc5TteHKqt3y/EbaJZ1w=

我正在尝试在在线工具中对其进行编码 - https://www.devglan.com/online-tools/aes-encryption-decryption。工具说密钥必须是 16 字节,所以我只使用密钥的一半 - 0123456789123456

它 returns 与 PHP 完全相同 结果。请注意 IV 是空的。

我需要使用 Crypto-js

在 JS 中进行相同的加密(而不是解密)
const CryptoJS = require('crypto-js');

var key = CryptoJS.lib.WordArray.create('01234567891234567890123456789012');
var iv = CryptoJS.lib.WordArray.create('');
//var iv = null;
// var iv = CryptoJS.enc.Hex.parse("");
// var iv = CryptoJS.enc.Base64.parse('');
let cfg = {
    mode: CryptoJS.mode.CBC,
    keySize: 128,
    iv: iv
};
const body = 'some string to encode';
const encryptedBody = CryptoJS.AES.encrypt(body, key, cfg).toString();
console.log( encryptedBody );
// result is VYCEPSx9nmb0FJGf1RiU/daL5nIk/qaJZU82jrlGQws=

类似示例位于 https://jsfiddle.net/pj76d5ov/

JS 中的结果 与 PHP 不同。有没有办法在没有 IV 的情况下使用 CryptoJS?

如果我使用 key 作为 string,CryptoJS 根据我的 key[=46= 生成 IV ], 所以我必须使用 WordArray 类型。

然后我尝试将iv更改为一些值,但没有帮助。设置 ivfalsenull,或者不发送 iv 完全报错。

在 PHP 代码中指定了 AES-128。因此 PHP 隐式地将 32 字节密钥截断为前 16 字节。在 CryptoJS 代码中只能使用这个 16 字节的密钥。
此外,使用 CryptoJS encoders 最容易将密钥和 IV 转换为 WordArray.
一个可能的 CryptoJS 实现是:

var key = CryptoJS.enc.Utf8.parse('0123456789123456');
var iv = CryptoJS.enc.Hex.parse('00000000000000000000000000000000');

let cfg = {
    mode: CryptoJS.mode.CBC,
    keySize: 128,
    iv: iv
};
const body = 'some string to encode';
const encryptedBody = CryptoJS.AES.encrypt(body, key, cfg).toString();
console.log( encryptedBody ); // result is 9VK02Mt8IaS+Bng8SbqhCVXUc5TteHKqt3y/EbaJZ1w=
<script src="https://cdnjs.cloudflare.com/ajax/libs/crypto-js/4.0.0/crypto-js.min.js"></script>

静态 IV 是不安全的,但你已经知道了。