PHP7.1 OpenSSL AES-128-ECB PKCS7填充加密结果异常问题
问题根源:填充方式不匹配
你遇到的问题核心很明确——你用的在线加密工具采用的是「无填充(No Padding)」,而PHP的openssl_encrypt默认启用了PKCS7填充,这直接导致了加密结果长度和内容的差异。
具体分析
AES-128的块大小是16字节,你的输入数据正好是32字节(64个十六进制字符),刚好是2个完整的AES块。这里的关键差异在填充规则:
- PKCS7填充(OpenSSL默认):即使输入长度是块大小的整数倍,也会额外添加一个完整的填充块(每个字节的值等于填充的字节数,也就是
0x10),所以你的加密结果多了16字节(对应输出里末尾的a254be88e037ddd9d79fb6411c3f9df8)。 - 无填充(在线工具):当输入长度正好是块大小的整数倍时,不会添加任何填充数据,所以结果正好是32字节,和你输出的前32字节完全一致。
修正代码
只需要在openssl_encrypt的参数里加上OPENSSL_ZERO_PADDING标志(注意:这个标志仅关闭自动填充,你必须确保输入已经是块大小的整数倍,你的输入已经满足这个条件):
// secret hex '2b7e151628aed2a6abf7158809cf4f3c' // input hex '6bc1bee22e409f96e93d7e117393172aae2d8a571e03ac9c9eb76fac45af8e51' // right output hex '3ad77bb40d7a3660a89ecaf32466ef97f5d3d58503b9699de785895a96fdbaaf' $secret = '2b7e151628aed2a6abf7158809cf4f3c'; $input = '6bc1bee22e409f96e93d7e117393172aae2d8a571e03ac9c9eb76fac45af8e51'; // 加上OPENSSL_ZERO_PADDING关闭自动填充 $output = openssl_encrypt(hex2bin($input), 'aes-128-ecb', hex2bin($secret), OPENSSL_RAW_DATA | OPENSSL_ZERO_PADDING); echo bin2hex($output); // 输出结果将与正确值完全一致
补充说明
- 如果你不确定输入是否总是块大小的整数倍,不要盲目使用
OPENSSL_ZERO_PADDING,否则会触发OpenSSL的错误。 - PKCS7是更安全通用的填充方式,大多数场景下推荐使用,但如果需要和特定系统(比如你测试的在线工具)兼容,就需要匹配对应的填充规则。
内容的提问来源于stack exchange,提问作者杨苏杭
相关产品推荐
相关产品推荐

