如何用PHP解密Java加密的字符串?附相关代码示例
问题描述
我用以下Java代码解密加密字符串:
SecretKey secretKey = new SecretKeySpec(build3DesKey(key), "DESede"); Cipher cipher = Cipher.getInstance("DESede"); cipher.init(Cipher.DECRYPT_MODE, secretKey); byte[] b = cipher.doFinal(str2ByteArray(dest)); String decoder = new String(b, "utf-8");
private static byte[] build3DesKey(String keyStr) throws Exception { byte[] key = new byte[24]; byte[] temp = keyStr.getBytes("utf-8"); if (key.length > temp.length) { System.arraycopy(temp, 0, key, 0, temp.length); } else { System.arraycopy(temp, 0, key, 0, key.length); } return key; }
尝试用PHP实现相同解密结果,但输出错误,我的PHP代码如下:
$data = '69C16E8142F2BDDE7569842BB0D68A3176624264E...'; $key = 'rpwdvbppnrvr56m123+#'; function decrypt($data, $secret) { //Generate a key from a hash $key = md5(utf8_encode($secret), true); //Take first 8 bytes of $key and append them to the end of $key. $key .= substr($key, 0, 8); $data = base64_decode($data); $data = mcrypt_decrypt('tripledes', $key, $data, 'ecb'); $block = mcrypt_get_block_size('tripledes', 'ecb'); $len = strlen($data); $pad = ord($data[$len-1]); return substr($data, 0, strlen($data) - $pad); } var_dump(utf8_encode(Decrypt($data, $key)));
请告诉我如何修改PHP代码以得到正确结果。
修改后的PHP代码及说明
核心修改点
- 密钥生成逻辑和Java完全对齐:直接取密钥字符串的UTF-8字节,不足24位补0,超过则截断前24位,无需MD5哈希
- 加密数据处理:Java的
str2ByteArray(dest)是十六进制转字节数组,对应PHP的hex2bin,而非Base64解码 - 补位处理:Java默认
DESede模式为ECB/PKCS5Padding,和PHP的mcrypt_decrypt默认行为匹配,需正确去除补位字节
完整正确代码
$data = '69C16E8142F2BDDE7569842BB0D68A3176624264E...'; $key = 'rpwdvbppnrvr56m123+#'; function decrypt($data, $secret) { // 生成与Java一致的24位密钥:UTF-8字节转码,不足补0,超过截断 $keyBytes = utf8_encode($secret); $key = str_pad($keyBytes, 24, "\0", STR_PAD_RIGHT); $key = substr($key, 0, 24); // 十六进制字符串转字节数组(对应Java的str2ByteArray) $data = hex2bin($data); // 3DES ECB模式解密 $decrypted = mcrypt_decrypt(MCRYPT_3DES, $key, $data, MCRYPT_MODE_ECB); // 去除PKCS5补位 $pad = ord(substr($decrypted, -1)); $blockSize = mcrypt_get_block_size(MCRYPT_3DES, MCRYPT_MODE_ECB); if ($pad > 0 && $pad <= $blockSize) { $decrypted = substr($decrypted, 0, -$pad); } return $decrypted; } var_dump(decrypt($data, $key));
详细说明
- 密钥生成:Java的
build3DesKey直接将密钥转UTF-8字节后处理成24位,PHP用str_pad补0、substr截断即可,之前的MD5哈希是结果错误的核心原因。 - 数据解码:Java的
str2ByteArray是十六进制转字节,PHP用hex2bin实现,替换掉错误的base64_decode。 - 补位处理:校验补位字节的合法性后再截断,避免因异常数据导致的错误截断。
内容的提问来源于stack exchange,提问作者Naruto Saitama
相关产品推荐
相关产品推荐

