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

如何从Python加密适配PHP的MCRYPT_RIJNDAEL_256解密逻辑?

解决Python与PHP mcrypt_decrypt(MCRYPT_RIJNDAEL_256, ECB)的加密适配问题

你的问题核心在于算法参数不匹配和填充逻辑错误,下面一步步拆解并给出修正方案:

1. 关键差异点分析

PHP端用的是MCRYPT_RIJNDAEL_256,这是块大小为256位(32字节)的Rijndael算法;而你Python里用的AES类是标准AES,它的块大小固定为128位(16字节)——即使你手动设置aes.block_size = 256也无效,因为标准AES不支持256位块大小,这是导致解密乱码的首要原因。

另外,PHP的mcrypt_decrypt在ECB模式下,当明文长度不是块大小的整数倍时,会自动用**NULL字节(\x00)**填充到块大小的整数倍;你之前按16字节填充,和PHP的32字节块大小不匹配,这是第二个问题。

2. 修正后的Python加密代码

首先安装支持完整Rijndael算法的库(推荐pycryptodome,因为pycrypto已停止维护):

pip install pycryptodome

然后修改加密逻辑,适配PHP的参数:

from Cryptodome.Cipher import Rijndael
import json

# 替换成你的实际密钥,确保是字节类型,和PHP的密钥编码一致(比如UTF-8)
__KEY__ = b"your_secret_key_here"
action = json.dumps({'test': 'value'})
block_size = 32  # RIJNDAEL_256的块大小是256位=32字节

# 实现和PHP mcrypt一致的NULL填充
padding_length = block_size - len(action) % block_size
# Python的'\0'等价于\x00,和PHP的NULL填充逻辑完全一致
action_padded = action + ('\0' * padding_length)

# 初始化Rijndael加密器,ECB模式,指定32字节块大小
cipher = Rijndael.new(__KEY__, Rijndael.MODE_ECB, block_size=block_size)
# 将填充后的字符串转成字节再执行加密
encrypted = cipher.encrypt(action_padded.encode('utf-8'))

3. 额外注意事项

  • 密钥处理:PHP的mcrypt_decrypt会自动将密钥截断/补NULL到算法支持的长度(RIJNDAEL_256支持128/192/256位密钥),Python里要确保密钥的字节长度和PHP端完全一致,比如如果PHP密钥是20字节,Python里也要用同样的20字节密钥(不要额外补全或截断)。
  • PHP解密后的处理:mcrypt_decrypt解密后不会自动去除末尾的NULL填充,所以PHP端需要手动清理:
    $decrypted = mcrypt_decrypt(MCRYPT_RIJNDAEL_256, __KEY__, $encrypted_data, MCRYPT_MODE_ECB);
    $json_str = rtrim($decrypted, "\x00"); // 去除末尾的NULL字节
    $value_object = json_decode($json_str);
    

这样调整后,Python加密的数据就能被PHP端正确解密了。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.27 06:57:16