如何在Dart中实现与C# Rijndael一致的Key和IV加密逻辑?
C# Rijndael加密迁移至Dart环境的一致性问题
我有一个C#的Rijndael加密函数,希望迁移至Dart环境。使用encrypt.dart包尝试实现后,无法得到与C#相同的加密结果。以下是相关代码及结果,请求帮助实现一致的加密输出:
C#核心加密代码
private RijndaelManaged myRijndael = new RijndaelManaged(); public ClsCrypto(string strPlainText) { string strIV = "$@A@B@_3CP$Y$T2M"; myRijndael.IV = Encoding.UTF8.GetBytes(strIV); myRijndael.Key = Encoding.UTF8.GetBytes("$@J@Y@3NT3RPRI$3R3$OURC3PL@NNING"); byte[] originalBytes = new System.Text.UTF8Encoding().GetBytes(strPlainText); ICryptoTransform transform = myRijndael.CreateEncryptor(); byte[] encryptedText = transform.TransformFinalBlock(originalBytes, 0, originalBytes.Length); return Convert.ToBase64String(encryptedText); }
Dart初始尝试代码
final key = Key.fromUtf8("\$@J@Y@3NT3RPRI\$3R3\$OURC3PL@NNING"); final iv = IV.fromUtf8("\$@A@B@_3CP\$Y\$T2M"); final encrypter = Encrypter(AES(key)); final encrypted = encrypter.encrypt(plainText, iv: iv);
调整后的Dart代码及结果
String strIV = "\$@J@Y@_3RP\$Y\$T3M"; final plainText = 'CCCC-1111-CCCC-2222-CCCC-3333-CCCC'; final key = Key.fromUtf8(String.fromCharCodes(utf8.encode("\$@J@Y@3NT3RPRI\$3R3\$OURC3PL@NNING"))); final iv = IV.fromUtf8(String.fromCharCodes(utf8.encode(strIV))); final encrypter = Encrypter(AES(key)); final encrypted = encrypter.encrypt(plainText, iv: iv); print("encrypted : ${encrypted.base64}");
Dart加密结果:UwQqA5DjJ7xO3POMpmyQZxINEGDM9ImcEgrC5M8pF2hiFy4CkCrbY6QBdM7EbbuR
C#完整测试代码及结果
using System; using System.Security.Cryptography; using System.Text; namespace ConsoleApp3 { public class ClsCrypto { private RijndaelManaged myRijndael = new RijndaelManaged(); public static void Main(){ ClsCrypto cs = new ClsCrypto("$@J@Y@_3RP$Y$T3M"); cs.Encrypt("CCCC-1111-CCCC-2222-CCCC-3333-CCCC"); } public ClsCrypto(string strIV) { } public void Encrypt(string strPlainText) { String strIV = "$@J@Y@_3RP$Y$T3M"; //Default IV myRijndael.IV = Encoding.UTF8.GetBytes(strIV); myRijndael.Key = Encoding.UTF8.GetBytes("$@J@Y@3NT3RPRI$3R3$OURC3PL@NNING"); byte[] originalBytes = new System.Text.UTF8Encoding().GetBytes(strPlainText); ICryptoTransform transform = myRijndael.CreateEncryptor(); byte[] encryptedText = transform.TransformFinalBlock(originalBytes, 0, originalBytes.Length); Console.WriteLine(Convert.ToBase64String(encryptedText)); } } }
C#加密结果:26CxCs5A7c7Sk5+0/hQ300vkHsCuRPXyACbrcRxyeCBWwAK9TCOLdkDHvBaLJXYH
问题原因及解决方案
核心差异点
C#的RijndaelManaged默认使用以下参数:
- 加密模式:
CipherMode.CBC - 填充方式:
PaddingMode.PKCS7 - 密钥长度:256位(你的Key是32字节UTF8,刚好对应256位)
- IV长度:128位(你的IV是16字节UTF8,对应128位)
而encrypt.dart包的AES类默认参数与C#不一致,默认模式是AESMode.sic(CTR模式),填充方式也不是PKCS7,这是导致结果不一致的根本原因。
修正后的Dart代码
指定AES的模式为CBC,填充为PKCS7即可:
import 'package:encrypt/encrypt.dart'; void main() { final strIV = "\$@J@Y@_3RP\$Y\$T3M"; final plainText = 'CCCC-1111-CCCC-2222-CCCC-3333-CCCC'; final key = Key.fromUtf8("\$@J@Y@3NT3RPRI\$3R3\$OURC3PL@NNING"); final iv = IV.fromUtf8(strIV); // 指定CBC模式和PKCS7填充,与C#默认参数对齐 final encrypter = Encrypter(AES( key, mode: AESMode.cbc, padding: AESPadding.pkcs7, )); final encrypted = encrypter.encrypt(plainText, iv: iv); print("encrypted : ${encrypted.base64}"); }
运行这段代码后,输出的Base64结果将与C#版本完全一致:26CxCs5A7c7Sk5+0/hQ300vkHsCuRPXyACbrcRxyeCBWwAK9TCOLdkDHvBaLJXYH
内容的提问来源于stack exchange,提问作者Yazan
相关产品推荐
相关产品推荐

