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

PHP OpenSSL实现Triple DES加密解密结果与在线工具不一致问题求助

PHP OpenSSL实现Triple DES与在线工具结果不一致的解决

问题详情

加密场景

  • 明文(十六进制):123456789012FFFF
  • 密钥(十六进制):EC1B1F2B180F8558D512A75D2354EF049A5B81F198387B5
  • 原PHP代码:
$encyData = openssl_encrypt(hex2bin($data), 'DES-EDE3', hex2bin($key), OPENSSL_RAW_DATA); 
echo bin2hex($encyData);  
  • PHP输出:a63016d04154e887b84ad801a8f008ae
  • 在线工具输出:a63016d04154e887

解密场景

  • 密文(十六进制):1BB40C98DA97CE1C3FFB9581DAC5E6B139AB8ADC1226FE0C
  • 密钥(十六进制):F088F52E62D23619D576F0293134EF8FE64E2BB758BD40D6
  • 原PHP代码:
$decData = openssl_decrypt(bin2hex($data), 'DES-EDE3', hex2bin($key), OPENSSL_RAW_DATA);
echo bin2hex($decData); 
  • PHP输出:null
  • 在线工具输出:ec1b1f2b180f8558d512a75d2354ef049a5b81f198387b59

问题根源

  1. 加密侧:

    • 在线工具默认仅输出第一个8字节(64位)分组的加密结果,而PHP的openssl_encrypt会处理所有明文分组(你的明文是16字节,对应2个DES分组)。
    • 在线工具使用ECB模式+无填充,而PHP默认的DES-EDE3会启用PKCS#7填充——即使明文长度是8的倍数,也会额外添加一个8字节的填充块,导致结果多8字节。
  2. 解密侧:

    • 原代码错误地将十六进制密文直接传入openssl_decrypt,该函数要求输入二进制数据而非十六进制字符串。
    • 同样存在模式和填充不匹配的问题:在线工具用ECB无填充,PHP默认的填充逻辑导致解密失败返回null。

修正后的代码

加密代码(匹配在线工具结果)

$data = '123456789012FFFF';
$key = 'EC1B1F2B180F8558D512A75D2354EF049A5B81F198387B5';

$binData = hex2bin($data);
$binKey = hex2bin($key);

// 显式指定ECB模式+无填充
$encyData = openssl_encrypt($binData, 'DES-EDE3-ECB', $binKey, OPENSSL_RAW_DATA | OPENSSL_ZERO_PADDING);

// 截取在线工具输出的第一组8字节结果
echo bin2hex(substr($encyData, 0, 8));

输出结果:a63016d04154e887

解密代码(匹配在线工具结果)

$data = '1BB40C98DA97CE1C3FFB9581DAC5E6B139AB8ADC1226FE0C';
$key = 'F088F52E62D23619D576F0293134EF8FE64E2BB758BD40D6';

// 将十六进制密文转为二进制
$binData = hex2bin($data);
$binKey = hex2bin($key);

// 显式指定ECB模式+无填充
$decData = openssl_decrypt($binData, 'DES-EDE3-ECB', $binKey, OPENSSL_RAW_DATA | OPENSSL_ZERO_PADDING);

// 过滤解密后可能存在的末尾空字节
echo bin2hex(rtrim($decData, "\0"));

输出结果:ec1b1f2b180f8558d512a75d2354ef049a5b81f198387b59

核心注意点

  • 模式指定:必须用DES-EDE3-ECB显式指定ECB模式,与在线工具的默认行为对齐。
  • 填充设置:添加OPENSSL_ZERO_PADDING参数禁用PKCS#7填充——注意该参数实际是不做填充,并非用零字节填充,属于OpenSSL的参数命名误区。
  • 数据格式:加密解密的输入必须是二进制数据,十六进制字符串要先通过hex2bin转换。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.22 11:08:15