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

使用相同密钥和数据时,PHP与Python的AES-256-CBC加密结果为何不同?

AES-256-CBC跨PHP/Python加密结果不一致的原因及解决方法

核心问题:密钥与IV的生成方式差异

你的代码里,PHP和Python生成密钥、IV的逻辑看似一致,实则存在本质区别:

  • PHP端:hash('sha256', $secret_key)默认返回十六进制字符串(每个字节用两个字符表示),substr(..., 0, 32)取的是32个十六进制字符,仅对应16字节的密钥,但AES-256需要32字节的密钥,直接导致密钥长度不足;同理,IV取16个十六进制字符(仅8字节),不符合CBC模式16字节IV的要求。
  • Python端:sha256(...).digest()返回的是原始字节串,[:32]取的是32字节密钥、[:16]取的是16字节IV,完全符合加密算法的要求。
  • 额外问题:PHP原代码中openssl_encrypt默认返回base64编码后的字符串,你又手动执行了一次base64_encode,导致做了两次base64编码,结果自然和Python不一致。

修正后的PHP代码

调整hash函数参数获取原始字节串,同时修正openssl_encrypt的输出模式:

<?php
$plaintextstr = 'AAAAAAAAAAAAAAAA';
$encrypt_method = "AES-256-CBC";
$secret_key = "SSSSSSSSSSSS";
$secret_iv = "LLLLLLLLLLLL";
// 生成32字节的AES-256密钥,第三个参数true让hash返回原始字节串
$key = substr(hash('sha256', $secret_key, true), 0, 32);
// 生成16字节的CBC模式IV
$iv = substr(hash('sha256', $secret_iv, true), 0, 16);
// OPENSSL_RAW_DATA让函数返回原始加密字节串,避免自动base64编码
$encrypted_str = openssl_encrypt($plaintextstr, $encrypt_method, $key, OPENSSL_RAW_DATA, $iv);
echo base64_encode($encrypted_str);
?>

验证说明

修正后,两端的加密逻辑完全对齐:

  • 密钥、IV均为SHA256哈希后的原始字节截取,长度符合算法要求
  • 填充逻辑统一为PKCS7(openssl_encrypt默认使用PKCS7填充,与Python的pad函数一致)
  • 最终仅执行一次base64编码

此时PHP与Python的加密结果将完全一致。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.18 20:13:10