C# AES CFB加解密模式兼容JAVA

时间:2022-12-02 22:55:49


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));
}
}
}
  1. 重点调试的参数就​​FeedbackSize​​,这个是CFB模式下特有的,常用的有8,64,128,这个现场恰恰用的是56这个模式。
  2. ​Aes128.Padding = PaddingMode.Zeros;​​ 设置Padding为0,这个也是要根据实际情况去调的。
  3. 还有要注意的就是​​byte[] savedKey = Convert.FromBase64String("5S1I25wtR6vdJrlPwF4E1Q==");​​,Key的编码方式,这边Java用的是Base64模式,刚开始我没注意,使用的是UTF8模式进行转换,调试过程中各种问题,最后发现了这个隐蔽问题。
static void Main(string[] args)
{
Example(7);
Console.ReadLine();
}

AES在线测试工具:​​在线测试工具​

C# AES CFB加解密模式兼容JAVA