将Python AES-ECB加密代码移植至PHP OpenSSL的问题解决
Python AES-ECB零填充加密移植到PHP OpenSSL的正确实现
原Python代码及输出
Python使用PyCryptodome实现AES-128-ECB模式,自定义零填充逻辑,加密结果如下:
from Crypto.Cipher import AES import base64 # 补充原代码缺失的导入,确保正常运行 def pad(data): block_size = 16 bytes_to_add = block_size - ((len(data) % block_size) or block_size) return data + (b'\0' * bytes_to_add) cipher = AES.new(b"4452038393672345", AES.MODE_ECB) body = pad("asa masa".encode('utf-8')) content = base64.b64encode(cipher.encrypt(body)).decode('ascii') # 最终输出:"sEP5RCWmdQdPYo/eeWVIwg=="
错误的PHP尝试及问题
最初编写的PHP代码未匹配Python的加密逻辑,导致结果不一致:
尝试1
function pad($data) { $block_size = 16; $bytes_to_add = $block_size - ((strlen($data) % $block_size) ?: $block_size); return $data . str_repeat("\0", $bytes_to_add); } $cipher = "AES-128-ECB"; $options = OPENSSL_RAW_DATA; $plainText = pad("asa masa"); $key = '4452038393672345'; $encryptedText = openssl_encrypt($plainText, $cipher, $key, $options); $encodedText = base64_encode($encryptedText); // 输出:"c0VQNVJDV21kUWRQWW8vZWVXVkl3dWZPTjExZ21iUG1VQUI0c0EwaktVaz0="
尝试2
$rawData = openssl_encrypt(pad("asa masa"), 'AES-128-ECB', '4452038393672345'); // 输出:"sEP5RCWmdQdPYo/eeWVIwufON11gmbPmUAB4sA0jKUk="
问题核心:
- PHP的
openssl_encrypt默认使用PKCS#7填充,与Python的自定义零填充逻辑冲突 - OpenSSL默认会对密钥做自动处理,未保持与Python一致的密钥使用方式
正确的PHP实现
通过指定OpenSSL的关键选项,实现与Python完全一致的加密结果:
function pad($data) { $block_size = 16; $bytes_to_add = $block_size - ((strlen($data) % $block_size) ?: $block_size); return $data . str_repeat("\0", $bytes_to_add); } $encrypted = openssl_encrypt( pad("asa masa"), 'AES-128-ECB', '4452038393672345', OPENSSL_RAW_DATA | OPENSSL_DONT_ZERO_PAD_KEY | OPENSSL_ZERO_PADDING ); $encrypted = base64_encode($encrypted); // 最终输出:"sEP5RCWmdQdPYo/eeWVIwg=="
选项说明
OPENSSL_RAW_DATA:返回原始二进制加密数据,而非自动base64编码的结果OPENSSL_DONT_ZERO_PAD_KEY:禁止对密钥进行零填充,保持密钥原样(与Python直接使用给定字节作为密钥的逻辑一致)OPENSSL_ZERO_PADDING:禁用默认的PKCS#7填充,依赖自定义的零填充逻辑
内容的提问来源于stack exchange,提问作者ambako
相关产品推荐
相关产品推荐

