简体   繁体   English

Node.js 加密库从 PHP opensll_encrypt 库返回不同的结果

[英]Node.js Crypto lib returning different result from PHP opensll_encrypt lib

My problem is as follows:我的问题如下:

I have a PHP script that is responsible for encrypting a string using AES-256-CBC encryption.我有一个 PHP 脚本,负责使用 AES-256-CBC 加密对字符串进行加密。 This script uses the openssl lib and returns an X result.此脚本使用 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\"}");
?>

when I run a JS script, responsible for doing the same, but using the Crypto lib, the result obtained is different from the previous X.当我运行一个 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');

The results of the scripts differ, even though, in theory, the encryption should be the same.脚本的结果不同,尽管理论上加密应该是相同的。

An example of return is as follows:返回示例如下:

  • For the php script: input -> ^y3Hk3JKGGgA output -> eTqD5Op389QS/TOoui5kAQ==对于 php 脚本:输入 -> ^y3Hk3JKGGgA输出 -> eTqD5Op389QS/TOoui5kAQ==

  • For the js script: input -> ^y3Hk3JKGGgA output -> HHfskOE1N+QxdGt9MTai5A==对于 js 脚本:输入 -> ^y3Hk3JKGGgA输出 -> HHfskOE1N+QxdGt9MTai5A==

The desired result is the PHP script, but I need to run the code in JS, can someone explain to me what I may be doing wrong?想要的结果是 PHP 脚本,但我需要在 JS 中运行代码,有人可以向我解释我可能做错了什么吗?

I tried different ways to execute the createCipheriv method, but they all return the same result (different from what I need, which is the result obtained through the PHP script)我尝试了不同的方式来执行createCipheriv方法,但是都返回相同的结果(和我需要的不同,是通过PHP脚本得到的结果)

Thank you in advance.先感谢您。

Thank you guys for trying to help, indeed I posted the question lacking some informations (actually when the question was made I didn't have all the pieces of information I needed).谢谢你们的帮助,确实我发布的问题缺少一些信息(实际上在提出问题时我没有我需要的所有信息)。

But posting here some facts and the solution encountered for my case.但是在这里发布一些事实和我的案例遇到的解决方案。

The different results in the cases above only happen for the first PHP function ("encryptData"), responsible for encrypting small texts.上述情况中的不同结果仅发生在第一个 PHP 函数(“encryptData”),负责加密小文本。 The second, responsible for encrypting large texts (more than 16 bits) worked fine, both in PHP and JS scripts.第二个,负责加密大文本(超过 16 位),在 PHP 和 JS 脚本中都运行良好。

The solution I encountered was making the padding needed for the AES-256 algorithm by myself.我遇到的解决方案是自己制作 AES-256 算法所需的填充。 The padding function provided by the Crypto lib didn't work, at least for my case. Crypto lib 提供的填充功能不起作用,至少对我而言是这样。

So I disabled the padding in my cypher class and make sure that the data sent to be encrypted was padded correctly until the length is multiple of 16. The end's code is below.所以我在我的 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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM