如何将Python实现的AES加密函数转换为运行结果一致的C#代码
C# AES-128-CFB 加密对齐Python实现方案
结果不匹配的核心原因
- 填充规则不一致:Python PyCryptodome库的CFB模式默认无填充,加密后密文长度和明文长度完全一致;你当前C#代码设置了
PaddingMode.PKCS7会自动对明文补位,导致密文长度和内容都和Python输出不符 - 反馈段大小不匹配:Python代码显式指定了
segment_size = 128,对应C#的RijndaelManaged需要显式设置FeedbackSize = 128,该参数默认值为8,是二者结果不一致的核心原因 - 注意:需要保证传入的key、IV字节长度符合AES规范:AES128对应key长度16字节,IV固定16字节,不要直接对长度不符的字符串用UTF8转字节数组,避免密钥/IV不匹配
修正后完整代码
using System.Security.Cryptography; using System.Text; public static string AesEncrypt(string plainText, string key, string iv) { byte[] plainBytes = Encoding.UTF8.GetBytes(plainText); byte[] keyBytes = Encoding.UTF8.GetBytes(key); byte[] ivBytes = Encoding.UTF8.GetBytes(iv); int plainLen = plainBytes.Length; int blockSize = 16; // BlockSize=128对应16字节 using (RijndaelManaged rm = new RijndaelManaged()) { rm.Key = keyBytes; rm.IV = ivBytes; rm.Mode = CipherMode.CFB; rm.BlockSize = 128; rm.FeedbackSize = 128; // 对应Python的segment_size=128参数 rm.Padding = PaddingMode.None; // 关闭自动填充 ICryptoTransform encryptor = rm.CreateEncryptor(); // 处理非块大小整数倍的明文 int alignedLen = ((plainLen + blockSize - 1) / blockSize) * blockSize; byte[] alignedPlain = new byte[alignedLen]; Buffer.BlockCopy(plainBytes, 0, alignedPlain, 0, plainLen); byte[] encryptedAligned = encryptor.TransformFinalBlock(alignedPlain, 0, alignedLen); // 截取和原明文等长的密文 byte[] resultBytes = new byte[plainLen]; Buffer.BlockCopy(encryptedAligned, 0, resultBytes, 0, plainLen); return ToBCDStringLower(resultBytes); } } public static string ToBCDStringLower(byte[] buffer) { StringBuilder sb = new StringBuilder(); foreach (byte b in buffer) { sb.Append(b.ToString("x2")); } return sb.ToString(); }
验证说明
验证时请确保Python和C#使用的key、iv、明文完全一致,若使用AES192/AES256加密,仅需调整传入的key长度为24字节/32字节即可,其余参数不需要修改。
内容的提问来源于stack exchange,提问作者IShirai_KurokoI
相关产品推荐
相关产品推荐

