You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

PHP转TypeScript:OpenSSL AES-CBC加密结果不一致问题排查

问题排查与解决方案

核心问题分析

你的TypeScript代码和PHP代码的关键差异有两点:

  1. PHP的md5()返回值类型:PHP中md5($str)默认返回32位十六进制字符串,而你的TS代码里直接用createHash('md5').update(...).digest()得到的是16字节二进制Buffer,这导致密钥完全不匹配。
  2. 加密数据的拼接方式:用binary编码拼接加密片段可能引入编码转换问题,直接操作Buffer更可靠。

修正后的TypeScript代码

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

// 生成IV:和PHP逻辑一致,SHA256二进制结果取前16字节
const secretIV = createHash('sha256')
  .update(this.ApiKey)
  .digest()
  .subarray(0, 16)

// 生成密钥:先将ApiSecret的MD5转为十六进制字符串,再转成32字节(补0)
const md5Hex = createHash('md5')
  .update(this.ApiSecret)
  .digest('hex') // 对应PHP的md5默认返回十六进制字符串
const key = Buffer.alloc(32)
key.write(md5Hex, 0, 'utf8') // 将十六进制字符串写入Buffer,不足部分自动补0

// 加密过程:直接操作Buffer,避免编码转换问题
const cipher = createCipheriv('aes-256-cbc', key, secretIV)
const encryptedBuffer = Buffer.concat([
  cipher.update(data, 'utf8'),
  cipher.final()
])

// 返回Base64URL字符串
return encryptedBuffer.toString('base64url')

关键修正点说明

  • 密钥生成:PHP的md5($this->ApiSecret)返回32字符的十六进制字符串,TS中必须用digest('hex')得到相同字符串,再写入32字节Buffer,和PHP的自动补0逻辑完全对齐。
  • 加密数据处理:用Buffer.concat直接拼接update和final的Buffer结果,避免binary编码带来的字符转换错误,和PHPOPENSSL_RAW_DATA输出的二进制数据完全匹配。
  • IV生成:原代码逻辑正确,SHA256二进制结果取前16字节,和PHP的substr(hash("SHA256", $this->ApiKey, true), 0, 16)一致。

验证建议

使用相同的ApiKey、ApiSecret和测试data分别运行PHP和修正后的TS代码,对比输出的Base64URL字符串,即可确认结果一致。

内容的提问来源于stack exchange,提问作者thim24

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.31 09:02:53