Python实现TripleDES ECB解密与C#结果不一致问题排查
C# TripleDES ECB零填充解密转Python实现问题修复
问题描述
需要将给定的C# TripleDES解密函数转换为等价Python实现,初始编写的Python代码解密结果和C#原函数输出不一致。
原始C#实现逻辑
public static string Decrypt(string Key, string toDecrypt) // key.length = 16 Byte { if (Key != "") { try { byte[] toEncryptArray = Convert.FromBase64String(toDecrypt); byte[] keyArray = UTF8Encoding.UTF8.GetBytes(Key); TripleDESCryptoServiceProvider tdes = new TripleDESCryptoServiceProvider(); tdes.Key = keyArray; tdes.Mode = CipherMode.ECB; tdes.Padding = PaddingMode.Zeros; ICryptoTransform cTransform = tdes.CreateDecryptor(); byte[] resultArray = cTransform.TransformFinalBlock(toEncryptArray, 0, toEncryptArray.Length); tdes.Clear(); return UTF8Encoding.UTF8.GetString(resultArray); } catch { return ""; } } else return ""; }
初始Python代码的错误点
- 密文处理方向错误:C#对密文参数做Base64解码得到待解密字节数组,初始代码误用
base64.b64encode做Base64编码,输入数据完全错误 - 密钥被额外修改:初始代码调用
DES3.adjust_key_parity修改了密钥的奇偶校验位,和C#直接使用传入UTF8字节作为密钥的逻辑不一致 - 填充处理缺失:C#使用ZeroPadding零填充模式,解密后需要移除末尾的
\x00填充字节,初始代码未做该处理 - 冗余导入:导入了
get_random_bytes、pad/unpad等未使用的模块,其中unpad是PKCS7填充用的,不匹配零填充逻辑
等价Python实现
import base64 from Crypto.Cipher import DES3 def decrypt(key: str, to_decrypt: str) -> str: if not key: return "" try: # Base64解码密文,对齐C# Convert.FromBase64String逻辑 to_encrypt_array = base64.b64decode(to_decrypt) key_array = key.encode('utf-8') # 初始化3DES解密器,ECB模式,自动兼容16字节双密钥3DES tdes = DES3.new(key_array, DES3.MODE_ECB) # 执行解密 result_array = tdes.decrypt(to_encrypt_array) # 处理ZeroPadding:移除末尾的零填充字节 result_array = result_array.rstrip(b'\x00') # 转UTF8字符串返回 return result_array.decode('utf-8') except: return "" # 测试 if __name__ == "__main__": mac = 'OtTL6k9yLn6VJIZRXRj1OA==' key = 'nOwy4iuE8c8WcktG' print(decrypt(key, mac))
逻辑对齐说明
- PyCryptodome的DES3模块原生支持传入16字节双密钥,会自动按3DES标准扩展为24字节有效密钥,和C#
TripleDESCryptoServiceProvider的密钥处理逻辑完全一致,不需要手动调整密钥奇偶位 - ZeroPadding本身不存储填充长度,直接移除末尾所有
\x00字节的处理方式和C#解密后返回的结果完全对齐,若明文本身末尾包含\x00字符会被截断,这是ZeroPadding模式的固有特性,和C#实现行为一致 - 异常捕获逻辑和C#完全对齐,任意步骤报错直接返回空字符串
内容的提问来源于stack exchange,提问作者יוסף קדח
相关产品推荐
相关产品推荐

