Java AES/CBC/PKCS5Padding加密转PHP匹配失败求助
解决PHP与Java AES/CBC/PKCS5Padding加密匹配问题
我仔细对比了你的Java实现和PHP代码,发现几个关键问题导致加密结果不匹配,下面是修正方案和详细解释:
核心问题分析
- 填充方式冲突:你手动实现了PKCS5填充,同时在
openssl_encrypt中指定了OPENSSL_ZERO_PADDING,这会导致OpenSSL跳过自动填充,而手动填充的逻辑和Java的PKCS5Padding存在细微差异(实际上Java的PKCS5Padding和PHP的PKCS7Padding在16字节块大小下是兼容的,应该让OpenSSL自动处理填充)。 - JSON序列化一致性:需要确保PHP生成的JSON字符串和Java完全一致,包括无多余空格、键值对的格式严格匹配。
- 密钥处理细节:需要和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
相关产品推荐
相关产品推荐

