我目前正致力于将加密算法从 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 代码,确保填充算法匹配(pcks5
和 pcks7
)并检查每个输入缓冲区的字节长度是否与 PHP 中的输入相同。我目前在想是否是某种二进制格式导致数据在 Javascript 中发生变化?
我希望有高手能帮我解答一下这个问题。也许我忽略了什么。提前致谢。