Nodejs 如何实现 OpenSSL AES-CBC 加密(来自 PHP)?

问题描述 投票:0回答:0

我目前正致力于将加密算法从 PHP 转换为 Typescript,以便在非常具体的 API 中使用,该 API 需要使用 API 密钥和 Secret 对发布的数据进行加密。这里提供了如何在 PHP 中正确加密数据以与 API 一起使用的示例(实现密钥和 IV 的方式不能更改):


$iv = substr(hash("SHA256", $this->ApiKey, true), 0, 16);
$key = md5($this->ApiSecret);

$output = openssl_encrypt($Data, "AES-256-CBC", $key, OPENSSL_RAW_DATA, $iv);
$completedEncryption = $this->base64Url_Encode($output);

return $completedEncryption;

在上面的代码中, base64Url_Encode 函数唯一做的就是将二进制数据转换为有效的 Base64URL 字符串

现在我在 Typescript 中实现的代码:

import { createHash, createCipheriv } from 'node:crypto'

const secretIV = createHash('sha256').update(this.ApiKey).digest().subarray(0, 16)

// Generate key
/* 
  Because the OpenSSL function in PHP automatically pads the string with /null chars,
  do the same inside NodeJS, so that CreateCipherIV can accept it as a 32-byte key, 
  instead of a 16-byte one.
*/
const md5 = createHash('md5').update(this.ApiSecret).digest()
const key = Buffer.alloc(32)
key.set(md5, 0)

// Create Cipher 
const cipher = createCipheriv('aes-256-cbc', key, secretIV)
    
let encrypted = cipher.update(data, 'utf8', 'binary');
encrypted += cipher.final('binary');

// Return base64URL string
return Buffer.from(encrypted).toString('base64url');

上面的 Typescript 代码只是没有给出与之前给出的 PHP 代码相同的输出。我查看了原始的 OpenSSL 代码,确保填充算法匹配(pcks5pcks7)并检查每个输入缓冲区的字节长度是否与 PHP 中的输入相同。我目前在想是否是某种二进制格式导致数据在 Javascript 中发生变化?

我希望有高手能帮我解答一下这个问题。也许我忽略了什么。提前致谢。

php node.js encryption byte php-openssl
© www.soinside.com 2019 - 2024. All rights reserved.