C# AES CFB加解密模式兼容JAVA代码片段
最近在和java做对接的时候老是遇到加密使用java写的,需要我们使用C#来解密相关数据,AES加解密平常也在用,但是这种跨语言的应用还是比较少,因为对方不知道使用的是哪些参数进行的加密,调试起来就比较耗时耗力,做个记录方便后期查漏补缺。
using System.Security.Cryptography;
static void Example(int i)
{
Console.WriteLine(i+">>>>>>");
//
// Encrypt a small sample of data
//
String Plain = "2121050";
byte[] plainBytes = Encoding.ASCII.GetBytes(Plain);
Console.WriteLine("plaintext length is" + plainBytes.Length);
Console.WriteLine("Plaintext is" + BitConverter.ToString(plainBytes));
byte[] savedKey = Convert.FromBase64String("5S1I25wtR6vdJrlPwF4E1Q==");
var d = BitConverter.ToString(savedKey).Replace("-"," ");
byte[] savedIV = new byte[16] {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
byte[] cipherBytes;
using (RijndaelManaged Aes128 = new RijndaelManaged())
{
//
// Specify a blocksize of 128, and a key size of 128, which make this
// instance of RijndaelManaged an instance of AES 128.
//
Aes128.BlockSize = 128;
Aes128.KeySize = 128;
//
// Specify CFB8 mode
//
Aes128.Mode = CipherMode.CFB;
Aes128.FeedbackSize = 8*i;
Aes128.Padding = PaddingMode.Zeros;
//
// Generate and save random key and IV.
//
//Aes128.GenerateKey();
//Aes128.GenerateIV();
Aes128.Key = savedKey;
Aes128.IV = savedIV;
//Aes128.Key.CopyTo(savedKey, 0);
//Aes128.IV.CopyTo(savedIV, 0);
using (var encryptor = Aes128.CreateEncryptor())
using (var msEncrypt = new MemoryStream())
using (var csEncrypt = new CryptoStream(msEncrypt, encryptor, CryptoStreamMode.Write))
using (var bw = new BinaryWriter(csEncrypt, Encoding.UTF8))
{
bw.Write(plainBytes);
bw.Close();
cipherBytes = msEncrypt.ToArray();
Console.WriteLine("Cipher length is" + cipherBytes.Length);
Console.WriteLine("Cipher text is" + BitConverter.ToString(cipherBytes));
Console.WriteLine("AES Base64:" + Convert.ToBase64String(cipherBytes));
}
}
//
// Now decrypt the cipher back to plaintext
//
using (RijndaelManaged Aes128 = new RijndaelManaged())
{
Aes128.BlockSize = 128;
Aes128.KeySize = 128;
Aes128.Mode = CipherMode.CFB;
Aes128.FeedbackSize = 8*i;
Aes128.Padding = PaddingMode.Zeros;
Aes128.Key = savedKey;
Aes128.IV = savedIV;
using (var decryptor = Aes128.CreateDecryptor())
using (var msEncrypt = new MemoryStream(cipherBytes))
using (var csEncrypt = new CryptoStream(msEncrypt, decryptor, CryptoStreamMode.Read))
using (var br = new BinaryReader(csEncrypt, Encoding.UTF8))
{
//csEncrypt.FlushFinalBlock();
plainBytes = br.ReadBytes(cipherBytes.Length);
Console.WriteLine("Decrypted plain length is" + plainBytes.Length);
Console.WriteLine("Decrypted plain text bytes is" + BitConverter.ToString(plainBytes));
Console.WriteLine("Decrypted plain text is" + Encoding.UTF8.GetString(plainBytes));
}
}
}
- 重点调试的参数就
FeedbackSize
,这个是CFB模式下特有的,常用的有8,64,128,这个现场恰恰用的是56这个模式。-
Aes128.Padding = PaddingMode.Zeros;
设置Padding为0,这个也是要根据实际情况去调的。- 还有要注意的就是
byte[] savedKey = Convert.FromBase64String("5S1I25wtR6vdJrlPwF4E1Q==");
,Key的编码方式,这边Java用的是Base64模式,刚开始我没注意,使用的是UTF8模式进行转换,调试过程中各种问题,最后发现了这个隐蔽问题。
static void Main(string[] args)
{
Example(7);
Console.ReadLine();
}
AES在线测试工具:在线测试工具