PHP与C#同参数AES-CBC加密结果不一致问题排查
PHP与C# AES跨语言加解密结果不匹配修复方案
核心问题
两边密钥、偏移量(IV)的传入格式不统一,是结果不一致的根本原因,和填充模式、加密模式无关:
- C#端通过
HexStringToByteArray()将传入的32位十六进制格式Key、IV字符串转为二进制,每2个十六进制字符对应1个字节,最终得到16字节长度的二进制Key/IV,自动匹配AES-128算法规格。 - PHP端直接将32位原始明文字符串作为Key、IV传入,每个字符'1'对应ASCII码0x31占1字节,相当于传入了32字节的Key跑AES-256-CBC;即使手动切换为AES-128-CBC,PHP取前16字节ASCII字符作为密钥,和C#转换后的16字节二进制密钥值完全不同,密文结果自然无法匹配。
补充说明:PHP的
openssl_encrypt默认确实使用PKCS7填充,和C#显式指定的PaddingMode.PKCS7逻辑完全一致,这部分不需要调整。
修复代码
PHP端需要先将十六进制格式的Key、IV转为二进制字节串,对齐C#的解析逻辑,同时指定匹配的AES-128-CBC算法即可:
$Test_String = "Testing"; $Key = "11111111111111111111111111111111"; $Iv = "11111111111111111111111111111111"; // 对齐C# HexStringToByteArray逻辑:十六进制字符串转二进制 $binaryKey = hex2bin($Key); $binaryIv = hex2bin($Iv); $cipherText = openssl_encrypt($Test_String, "AES-128-CBC", $binaryKey, OPENSSL_RAW_DATA, $binaryIv); $encString = strtoupper(bin2hex($cipherText)); // 输出结果:79A300CB4BA568EF10B941113A4F887F,和C#结果完全一致 echo $encString;
对齐校验点
跨语言AES加解密要保证结果一致,必须同时满足以下条件:
- 密钥、IV的编码/解析逻辑完全统一:是传原始字符串、Base64字符串还是十六进制字符串,两边必须做相同的转换得到相同的二进制字节序列
- 算法的密钥长度、工作模式(CBC/ECB等)完全匹配
- 填充模式完全匹配
- 明文的编码规则统一(如统一用UTF-8、ASCII等)
- 密文的输出格式统一(如统一转十六进制、Base64等)
内容的提问来源于stack exchange,提问作者Chandru
相关产品推荐
相关产品推荐

