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

如何用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));

详细说明

  1. 密钥生成:Java的build3DesKey直接将密钥转UTF-8字节后处理成24位,PHP用str_pad补0、substr截断即可,之前的MD5哈希是结果错误的核心原因。
  2. 数据解码:Java的str2ByteArray是十六进制转字节,PHP用hex2bin实现,替换掉错误的base64_decode。
  3. 补位处理:校验补位字节的合法性后再截断,避免因异常数据导致的错误截断。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.20 12:36:26