Node.js 加密库从 PHP opensll_encrypt 库返回不同的结果
Node.js Crypto lib returning different result from PHP opensll_encrypt lib
我的问题如下:
我有一个 PHP 脚本负责使用 AES-256-CBC 加密来加密字符串。此脚本使用 openssl 库和 returns 一个 X 结果。
<?php
class AES
{
const PRIVATE_KEY = 'abcdefghijklmnnoabcdefghijklmnno';
const ENCRYPT_METHOD = 'aes-256-cbc';
const VECTOR = 'abcdefghijklmnno';
public function encryptData($data)
{
while(strlen($data) < 16) $data .= "[=13=]";
return openssl_encrypt($data, self::ENCRYPT_METHOD, self::PRIVATE_KEY, OPENSSL_ZERO_PADDING, self::VECTOR);
}
public function encryptDataL($data)
{
return openssl_encrypt($data, self::ENCRYPT_METHOD, self::PRIVATE_KEY, 0, self::VECTOR);
}
public function decryptData($data)
{
return openssl_decrypt($data, self::ENCRYPT_METHOD, self::PRIVATE_KEY, OPENSSL_ZERO_PADDING, self::VECTOR);
}
}
$aes = new AES();
echo $aes->encryptData("abcdefghijkl");
echo "\n";
echo $aes->encryptDataL("{\"REQUEST\": [{\"MSISDN\": \"32156489721\",\"IDPRODUCT\": 123,\"IDOPERATOR\": 12345,\"OUTPUTFORMAT\": \"JSON\"}],\"OUTPUTFORMAT\": \"json\"}");
?>
当我运行一个JS脚本,负责做同样的事情,但是使用了Crypto lib,得到的结果和之前的X不一样
const crypto = require('crypto');
const cipher = crypto.createCipheriv('aes-256-cbc', 'abcdefghijklmnnoabcdefghijklmnno', 'abcdefghijklmnno');
let crypted = cipher.update(data, 'utf8', 'base64');
crypted += cipher.final('base64');
尽管理论上加密应该相同,但脚本的结果不同。
return的例子如下:
对于php脚本:输入 -> ^y3Hk3JKGGgA 输出 -> eTqD5Op389QS/TOoui5kAQ==
对于js脚本:输入-> ^y3Hk3JKGGgA输出-> HHfskOE1N+QxdGt9MTai5A==
想要的结果是 PHP 脚本,但是我需要 运行 JS 中的代码,有人可以向我解释我可能做错了什么吗?
我尝试了不同的方式来执行createCipheriv方法,但都return相同的结果(与我需要的不同,是通过PHP脚本得到的结果)
提前致谢。
谢谢你们的帮助,确实我发布的问题缺少一些信息(实际上在提出问题时我没有我需要的所有信息)。
但在这里发布一些事实和我遇到的解决方案。
上述情况中的不同结果仅发生在第一个 PHP 函数(“encryptData”)中,该函数负责加密小文本。第二个负责加密大文本(超过 16 位),在 PHP 和 JS 脚本中都运行良好。
我遇到的解决办法是自己制作AES-256算法需要的padding。 Crypto 库提供的填充函数不起作用,至少对我来说是这样。
所以我在我的密码中禁用了填充class并确保发送要加密的数据被正确填充直到长度是16的倍数。结束代码如下。
encryptWithAES256(data) {
// added padding until data length is multiple of 16
let paddedData = data;
while (paddedData.length % 16 !== 0) {
paddedData += '[=10=]';
}
// ciphers data
const cipher = crypto.createCipheriv('aes-256-cbc', encodeKey, IV);
cipher.setAutoPadding(false);
let crypted = cipher.update(paddedData, 'utf8', 'base64');
crypted += cipher.final('base64');
return crypted;
}
我的问题如下:
我有一个 PHP 脚本负责使用 AES-256-CBC 加密来加密字符串。此脚本使用 openssl 库和 returns 一个 X 结果。
<?php
class AES
{
const PRIVATE_KEY = 'abcdefghijklmnnoabcdefghijklmnno';
const ENCRYPT_METHOD = 'aes-256-cbc';
const VECTOR = 'abcdefghijklmnno';
public function encryptData($data)
{
while(strlen($data) < 16) $data .= "[=13=]";
return openssl_encrypt($data, self::ENCRYPT_METHOD, self::PRIVATE_KEY, OPENSSL_ZERO_PADDING, self::VECTOR);
}
public function encryptDataL($data)
{
return openssl_encrypt($data, self::ENCRYPT_METHOD, self::PRIVATE_KEY, 0, self::VECTOR);
}
public function decryptData($data)
{
return openssl_decrypt($data, self::ENCRYPT_METHOD, self::PRIVATE_KEY, OPENSSL_ZERO_PADDING, self::VECTOR);
}
}
$aes = new AES();
echo $aes->encryptData("abcdefghijkl");
echo "\n";
echo $aes->encryptDataL("{\"REQUEST\": [{\"MSISDN\": \"32156489721\",\"IDPRODUCT\": 123,\"IDOPERATOR\": 12345,\"OUTPUTFORMAT\": \"JSON\"}],\"OUTPUTFORMAT\": \"json\"}");
?>
当我运行一个JS脚本,负责做同样的事情,但是使用了Crypto lib,得到的结果和之前的X不一样
const crypto = require('crypto');
const cipher = crypto.createCipheriv('aes-256-cbc', 'abcdefghijklmnnoabcdefghijklmnno', 'abcdefghijklmnno');
let crypted = cipher.update(data, 'utf8', 'base64');
crypted += cipher.final('base64');
尽管理论上加密应该相同,但脚本的结果不同。
return的例子如下:
对于php脚本:输入 -> ^y3Hk3JKGGgA 输出 -> eTqD5Op389QS/TOoui5kAQ==
对于js脚本:输入-> ^y3Hk3JKGGgA输出-> HHfskOE1N+QxdGt9MTai5A==
想要的结果是 PHP 脚本,但是我需要 运行 JS 中的代码,有人可以向我解释我可能做错了什么吗?
我尝试了不同的方式来执行createCipheriv方法,但都return相同的结果(与我需要的不同,是通过PHP脚本得到的结果)
提前致谢。
谢谢你们的帮助,确实我发布的问题缺少一些信息(实际上在提出问题时我没有我需要的所有信息)。
但在这里发布一些事实和我遇到的解决方案。
上述情况中的不同结果仅发生在第一个 PHP 函数(“encryptData”)中,该函数负责加密小文本。第二个负责加密大文本(超过 16 位),在 PHP 和 JS 脚本中都运行良好。
我遇到的解决办法是自己制作AES-256算法需要的padding。 Crypto 库提供的填充函数不起作用,至少对我来说是这样。
所以我在我的密码中禁用了填充class并确保发送要加密的数据被正确填充直到长度是16的倍数。结束代码如下。
encryptWithAES256(data) {
// added padding until data length is multiple of 16
let paddedData = data;
while (paddedData.length % 16 !== 0) {
paddedData += '[=10=]';
}
// ciphers data
const cipher = crypto.createCipheriv('aes-256-cbc', encodeKey, IV);
cipher.setAutoPadding(false);
let crypted = cipher.update(paddedData, 'utf8', 'base64');
crypted += cipher.final('base64');
return crypted;
}