using System.Security.Cryptography;
using System.Collections;
public static void Main(string[] args)
AESTool aes = new AESTool();
var source = @"Washington (CNN)The Trump administration is formulating a long-term plan to punish China on multiple fronts for the coronavirus pandemic, injecting a rancorous new element into a critical relationship already on a steep downward slide.";
var key = "Today is my birthday";
var IV = "initialization vector";
var sourceEncoding = Encoding.ASCII.GetBytes(source);
var resultEncrypt = aes.AesCBCEncrypt(sourceEncoding, aes.StringConvert2MD5Byte(key), aes.StringConvert2MD5Byte(IV));
var resultDecrypt = aes.AesCBCDecrypt(resultEncrypt, aes.StringConvert2MD5Byte(key), aes.StringConvert2MD5Byte(IV));
Console.WriteLine("Key: " + key);
Console.WriteLine("IV : " + IV);
Console.WriteLine("Key: " + aes.StringConvert2MD5String(key));
Console.WriteLine("IV : " + aes.StringConvert2MD5String(IV));
Console.WriteLine("Encrypt: " + source);
Console.WriteLine("Decrypt: " + Encoding.UTF8.GetString(resultDecrypt));
public void XORPlainttext(byte[] plaintext_, int startIndex_, int plaintextOffset_, byte[] iv_)
for(int i = 0; i < iv_.Length; i++, startIndex_++)
plaintext_[startIndex_] = (byte)(plaintext_[startIndex_] ^ iv_[i]);
public byte[] AesCBCEncrypt(byte[] plaintext_, byte[] key_, byte[] iv_)
plaintext_ = Padding(plaintext_);
byte[] _currentIv = new byte[16];
XORPlainttext(plaintext_, 0, 16, iv_);
AesEcbEncrypt(plaintext_, 0, 16, plaintext_, 0, key_);
Array.Copy(plaintext_, 0, _currentIv, 0, 16);
for (int i = 16; i < plaintext_.Length; i = i + 16)
XORPlainttext(plaintext_, i, 16, _currentIv);
AesEcbEncrypt(plaintext_, i, 16, plaintext_, i, key_);
Array.Copy(plaintext_, i, _currentIv, 0, 16);
public void AesEcbEncrypt(byte[] plaintext_, int plaintextOffset_, int count_, byte[] cyphertext_, int cyphertextOffset_, byte[] key_)
using (var aesManaged = new AesManaged()
KeySize = key_.Length * 8,
Padding = PaddingMode.None,
IV = new byte[] { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }
var encryptor = aesManaged.CreateEncryptor(aesManaged.Key, aesManaged.IV);
int parameter = encryptor.TransformBlock(plaintext_, plaintextOffset_, count_, cyphertext_, cyphertextOffset_);
public byte[] AesCBCDecrypt(byte[] ciphertext_, byte[] key_, byte[] iv_)
var _nextIv = new byte[16];
Array.Copy(ciphertext_, 0, _nextIv, 0, 16);
AesEcbDecrypt(ciphertext_, 0, 16, ciphertext_, 0, key_);
XORPlainttext(ciphertext_, 0, 16, iv_);
for (int i = 16; i < ciphertext_.Length; i = i + 16)
Array.Copy(_nextIv, 0, iv_, 0, 16);
Array.Copy(ciphertext_, i, _nextIv, 0, 16);
AesEcbDecrypt(ciphertext_, i, 16, ciphertext_, i, key_);
XORPlainttext(ciphertext_, i, 16, iv_);
public void AesEcbDecrypt(byte[] ciphertext_, int ciphertextOffset_, int count_, byte[] plaintext_, int plaintextOffset_, byte[] key_)
using (var aesManaged = new AesManaged()
KeySize = key_.Length * 8,
Padding = PaddingMode.None,
IV = new byte[] { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }
var decryptor = aesManaged.CreateDecryptor(aesManaged.Key, aesManaged.IV);
int parameter = decryptor.TransformBlock(ciphertext_, ciphertextOffset_, count_, plaintext_, plaintextOffset_);
public byte[] Padding(byte[] source_)
var remainder = source_.Length % 16 == 0 ? Convert.ToByte(16) : Convert.ToByte(16 - (source_.Length % 16));
var paddingBytes = new byte[source_.Length + remainder];
source_.CopyTo(paddingBytes, 0);
for (int i = source_.Length ; i < paddingBytes.Length; i++)
paddingBytes[i] = remainder;
public string StringConvert2MD5String(string key_)
var stringBulider = new StringBuilder();
foreach (var bytes in StringConvert2MD5Byte(key_))
stringBulider.Append(bytes.ToString("X2"));
return stringBulider.ToString();
public byte[] StringConvert2MD5Byte(string key_)
using (MD5 md5 = MD5.Create())
return md5.ComputeHash(Encoding.UTF8.GetBytes(key_));
public string Byts2String(byte[] source_)
StringBuilder sb = new StringBuilder();
foreach (var byt in source_)
sb.Append(byt.ToString("X2"));