![](/img/trans.png)
[英]Node.js `crypto.final` make the encrypted result is different to PHP `mcrypt_encrypt`
[英]Node.js Crypto lib returning different result from PHP opensll_encrypt lib
我的问题如下:
我有一个 PHP 脚本,负责使用 AES-256-CBC 加密对字符串进行加密。 此脚本使用 openssl 库并返回 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 .= "\0";
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');
脚本的结果不同,尽管理论上加密应该是相同的。
返回示例如下:
对于 php 脚本:输入 -> ^y3Hk3JKGGgA输出 -> eTqD5Op389QS/TOoui5kAQ==
对于 js 脚本:输入 -> ^y3Hk3JKGGgA输出 -> HHfskOE1N+QxdGt9MTai5A==
想要的结果是 PHP 脚本,但我需要在 JS 中运行代码,有人可以向我解释我可能做错了什么吗?
我尝试了不同的方式来执行createCipheriv方法,但是都返回相同的结果(和我需要的不同,是通过PHP脚本得到的结果)
先感谢您。
谢谢你们的帮助,确实我发布的问题缺少一些信息(实际上在提出问题时我没有我需要的所有信息)。
但是在这里发布一些事实和我的案例遇到的解决方案。
上述情况中的不同结果仅发生在第一个 PHP 函数(“encryptData”),负责加密小文本。 第二个,负责加密大文本(超过 16 位),在 PHP 和 JS 脚本中都运行良好。
我遇到的解决方案是自己制作 AES-256 算法所需的填充。 Crypto lib 提供的填充功能不起作用,至少对我而言是这样。
所以我在我的 cypher 类中禁用了填充,并确保发送要加密的数据被正确填充,直到长度是 16 的倍数。最后的代码如下。
encryptWithAES256(data) {
// added padding until data length is multiple of 16
let paddedData = data;
while (paddedData.length % 16 !== 0) {
paddedData += '\0';
}
// 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;
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.