在PHP中将PHP openssl_encrypt与空白IV匹配

时间:2017-08-18 12:23:22

标签: javascript php cryptojs php-openssl

如果在PHP中没有声明IV并且使用了不合规的密钥长度,我如何匹配JavaScript中php -r '$value = openssl_encrypt("test", "AES-128-CBC", "aaaaaaaaaaaaaaaaaaaaaaaaaaaaa"); echo $value;' /u+5lB/VwbMX9U1YY4cnCQ== 的输出?

PHP

iv  = CryptoJS.enc.Utf8.parse("");
var encrypted = CryptoJS.AES.encrypt("test", "aaaaaaaaaaaaaaaaaaaaaaaaaaaaa", {iv: iv, mode: CryptoJS.mode.CBC, padding: CryptoJS.pad.Pkcs7});
console.log(encrypted.toString());

U2FsdGVkX19Cn1f6x8C/rJdfwzsZk5m5WWCUrR4z3U4=

console.log(CryptoJS.enc.Base64.stringify(encrypted.ciphertext));

l1/DOxmTmblZYJStHjPdTg==

的JavaScript

openssl_decrypt

我只能修改Javascript代码,我需要一种方法来加密字符串,以便PHP可以解密Base64.stringify。如果它是从PHP加密的字符串,它显然工作正常。

据我所知,通过不声明IV会使代码不那么安全,但在我的特定情况下,它不是一个大问题。

我已经读过其他主题,PHP默认填充到Pkcs7,这就是我将它添加到JS方法的原因。

我目前的理论是PHP的默认IV是问题,或者需要进一步处理JS函数的输出。如您所见,我尝试了{{1}}方法,但结果仍然不同。

此处使用的示例密钥与实际密钥的长度相同。

我使用https://github.com/sytelus/CryptoJS/blob/master/rollups/aes.js(无论我在JS中使用什么,它都需要像独立文件一样轻松分发,占用空间相对较小)

1 个答案:

答案 0 :(得分:1)

您的代码存在一些问题:

  • 如果您想使用现有密钥,则需要向WordArray提供CryptoJS.<cipher>.encrypt对象。这意味着它必须以某种方式解析。如果您只是提供一个字符串作为&#34;键&#34;,那么CryptoJS将假定它是一个密码,生成一个随机盐并使用EVP_BytesToKey从密码和盐派生密钥和IV。
  • 你的关键&#34;是29个字符长。 AES仅支持三种密钥大小:16,24和32字节。由于您在PHP中使用了AES-128,因此需要在CryptoJS中提供一个16字节的密钥,以便自动选择AES-128。请记住:密钥应该是随机选择的,并且与随机噪声无法区分,因此它具有某种安全性。如果必须以某种方式打印密钥,请使用Hex或Base64编码。

完整示例:

&#13;
&#13;
var iv  = CryptoJS.enc.Utf8.parse("");
var key = CryptoJS.enc.Utf8.parse("aaaaaaaaaaaaaaaa");
var encrypted = CryptoJS.AES.encrypt("test", key, {
    iv: iv, 
    mode: CryptoJS.mode.CBC, 
    padding: CryptoJS.pad.Pkcs7
});

console.log(CryptoJS.enc.Base64.stringify(encrypted.ciphertext));
&#13;
<script src="https://cdn.rawgit.com/CryptoStore/crypto-js/3.1.2/build/rollups/aes.js"></script>
&#13;
&#13;
&#13;