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

Java AES/CBC/PKCS5Padding加密转PHP匹配失败求助

解决PHP与Java AES/CBC/PKCS5Padding加密匹配问题

我仔细对比了你的Java实现和PHP代码,发现几个关键问题导致加密结果不匹配,下面是修正方案和详细解释:

核心问题分析

  1. 填充方式冲突:你手动实现了PKCS5填充,同时在openssl_encrypt中指定了OPENSSL_ZERO_PADDING,这会导致OpenSSL跳过自动填充,而手动填充的逻辑和Java的PKCS5Padding存在细微差异(实际上Java的PKCS5Padding和PHP的PKCS7Padding在16字节块大小下是兼容的,应该让OpenSSL自动处理填充)。
  2. JSON序列化一致性:需要确保PHP生成的JSON字符串和Java完全一致,包括无多余空格、键值对的格式严格匹配。
  3. 密钥处理细节:需要和Java逻辑对齐,截取密钥的前16个字符作为AES密钥。

修正后的PHP代码

function encrypt($data, $key) {
    // 生成与Java完全一致的紧凑JSON字符串,确保格式严格匹配
    $json = json_encode($data, JSON_UNESCAPED_SLASHES | JSON_FORCE_OBJECT);
    // 截取密钥前16个字符,和Java的substring(0,16)行为对齐
    $aesKey = substr($key, 0, 16);
    // 生成16字节全0的初始化向量,和Java逻辑一致
    $iv = str_repeat(chr(0), 16);
    // 使用AES-128-CBC,让OpenSSL自动处理PKCS7填充(兼容Java的PKCS5Padding)
    $encrypted = openssl_encrypt($json, 'AES-128-CBC', $aesKey, OPENSSL_RAW_DATA, $iv);
    return base64_encode($encrypted);
}

$key = 'c-MCjRx4X-pD-Lux';
$data = ['addrMatch' => 'N'];
echo encrypt($data, $key);

关键修正点说明

  • JSON序列化:添加JSON_FORCE_OBJECT确保生成标准的JSON对象格式,JSON_UNESCAPED_SLASHES避免斜杠被转义,最终生成的JSON和Java的{"addrMatch":"N"}完全一致。
  • 密钥处理:用substr($key, 0, 16)截取前16个字符,和Java代码中APISecretMerchant.substring(0,16)的逻辑完全对齐。
  • IV生成:用str_repeat(chr(0), 16)生成16个ASCII 0字节的IV,比手动拼接'\0'更清晰且不易出错。
  • 加密参数:移除OPENSSL_ZERO_PADDING,让OpenSSL自动使用PKCS7填充(和Java的PKCS5Padding在16字节块大小下完全兼容),OPENSSL_RAW_DATA确保输出原始加密字节流,再进行Base64编码。

运行修正后的代码,你会得到预期的结果:q8zzcOYHKggpSFXdmdZdObe2R/1EWnFgco2FJzjhtJQ=

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.11 07:46:36