AES加解密Java代码转PHP后无法解密求助
问题分析与解决
你的PHP代码解密失败的核心问题在于两处关键逻辑与Java代码不匹配,以下是具体问题和修复方案:
1. 自定义十六进制解码不匹配
Java代码中的decodeBytes是自定义的十六进制编码规则:用小写字母a-p对应十六进制的0-F(例如a=0、p=15),但你在PHP中使用了标准的hex2bin()函数——它仅能处理0-9a-f的标准十六进制字符串,这直接导致密文解码错误。
2. IV向量处理错误
Java代码中直接将IV字符串转为UTF-8字节数组,而你在PHP中错误地对IV执行了hex2bin()操作,破坏了IV的原始字节内容。
修复后的PHP代码
<?php $encryptedData = "lmncpiedimdofipgnokfeppgfncimkac"; $secretKey = "0123456789ABCDEF"; // 16-character key $iv = "0123456789ABCDEF"; // 16-character initialization vector try { $decryptedData = decrypt($encryptedData, $secretKey, $iv); echo "Decrypted data: " . $decryptedData; } catch (Exception $e) { echo "Error while decrypting: " . $e->getMessage(); } function decrypt($decData, $secretKey, $vector) { // 复刻Java版decodeBytes的自定义十六进制解码逻辑 $decodedBytes = decodeBytes($decData); $cipher = "AES-128-CBC"; // 使用OPENSSL_RAW_DATA处理原始字节输入 $options = OPENSSL_RAW_DATA; // IV直接转为UTF-8字节,与Java逻辑一致 $ivBytes = mb_convert_encoding($vector, 'UTF-8'); $decryptedData = openssl_decrypt($decodedBytes, $cipher, $secretKey, $options, $ivBytes); if ($decryptedData === false) { throw new Exception('Decryption failed: ' . openssl_error_string()); } return $decryptedData; } // 对应Java的decodeBytes函数 function decodeBytes($str) { $bytes = []; $length = strlen($str); for ($i = 0; $i < $length; $i += 2) { $c1 = $str[$i]; $c2 = $str[$i+1]; // 计算高4位:c1 - 'a' 后左移4位 $byte = (ord($c1) - ord('a')) << 4; // 加上低4位:c2 - 'a' $byte += (ord($c2) - ord('a')); $bytes[] = chr($byte); } return implode('', $bytes); } ?>
验证说明
- 自定义
decodeBytes函数完全复刻Java版本逻辑,确保密文解码后的字节与Java一致。 - IV直接转换为UTF-8字节,和Java的
vector.getBytes("utf-8")行为对齐。 - 使用
OPENSSL_RAW_DATA选项,让openssl_decrypt直接处理原始字节输入,解密结果直接对应Java中new String(original, "utf-8")的输出。
内容的提问来源于stack exchange,提问作者Sagar
相关产品推荐
相关产品推荐

