Skip to content

Instantly share code, notes, and snippets.

@magicsih
Last active May 4, 2023 12:33
Show Gist options
  • Star 12 You must be signed in to star a gist
  • Fork 5 You must be signed in to fork a gist
  • Save magicsih/be06c2f60288b54d9f52856feb96ce8c to your computer and use it in GitHub Desktop.
Save magicsih/be06c2f60288b54d9f52856feb96ce8c to your computer and use it in GitHub Desktop.
AES Encryption/Decryption Example in C#
using System.Security.Cryptography;
using System.Text;
namespace AesExample
{
class Program
{
private const string ORIGINAL = "this is some data to encrypt";
private const string SAMPLE_KEY = "gCjK+DZ/GCYbKIGiAt1qCA==";
private const string SAMPLE_IV = "47l5QsSe1POo31adQ/u7nQ==";
static void Main(string[] args)
{
// If there are no arguments in the constructor, the key and IV are generated automatically.
// AesEncryption aes = new AesEncryption();
AesEncryption aes = new AesEncryption(SAMPLE_KEY, SAMPLE_IV);
Console.WriteLine("original text:" + ORIGINAL);
Console.WriteLine("key:" + aes.GetBase64Key());
Console.WriteLine("iv:" + aes.GetBase64IV());
// Example for: string -> byte -> string
Console.WriteLine("example for: string->byte->string");
byte[] encryptedBlock = aes.EncryptToByte(ORIGINAL); // Convert original text to an encrypted byte array
string decryptedString = aes.Decrypt(encryptedBlock); // Decrypt the encrypted byte array to the original text
Console.WriteLine(decryptedString);
// Example for: string -> base64 -> string
Console.WriteLine("example for: string->base64->string");
string encryptedBase64String = aes.EncryptToBase64String(ORIGINAL); // Convert original text to an encrypted base64 string
decryptedString = aes.DecryptFromBase64String(encryptedBase64String); // Decrypt the encrypted base64 string to the original text
Console.WriteLine("encrypted base64:" + encryptedBase64String);
Console.WriteLine("decrypted text:" + decryptedString);
Console.ReadLine();
}
}
class AesEncryption
{
private readonly Aes aes = Aes.Create();
private readonly UnicodeEncoding unicodeEncoding = new UnicodeEncoding();
private const int CHUNK_SIZE = 128;
private void InitializeAes()
{
aes.Mode = CipherMode.CBC;
aes.Padding = PaddingMode.PKCS7;
}
public AesEncryption()
{
InitializeAes();
aes.KeySize = CHUNK_SIZE;
aes.BlockSize = CHUNK_SIZE;
aes.GenerateKey();
aes.GenerateIV();
}
public AesEncryption(string base64key, string base64iv)
{
InitializeAes();
aes.Key = Convert.FromBase64String(base64key);
aes.IV = Convert.FromBase64String(base64iv);
}
public AesEncryption(byte[] key, byte[] iv)
{
InitializeAes();
aes.Key = key;
aes.IV = iv;
}
public string Decrypt(byte[] cipher)
{
ICryptoTransform transform = aes.CreateDecryptor();
byte[] decryptedValue = transform.TransformFinalBlock(cipher, 0, cipher.Length);
return unicodeEncoding.GetString(decryptedValue);
}
public string DecryptFromBase64String(string base64cipher)
{
return Decrypt(Convert.FromBase64String(base64cipher));
}
public byte[] EncryptToByte(string plain)
{
ICryptoTransform encryptor = aes.CreateEncryptor();
byte[] cipher = unicodeEncoding.GetBytes(plain);
byte[] encryptedValue = encryptor.TransformFinalBlock(cipher, 0, cipher.Length);
return encryptedValue;
}
public string EncryptToBase64String(string plain)
{
return Convert.ToBase64String(EncryptToByte(plain));
}
public string GetBase64Key()
{
return Convert.ToBase64String(aes.Key);
}
public string GetBase64IV()
{
return Convert.ToBase64String(aes.IV);
}
public override string ToString()
{
return "key:" + GetBase64Key() + Environment.NewLine + "iv:" + GetBase64IV();
}
}
}
@oscarvalenzuelab
Copy link

Hi,

Great code! I would love to use it in my project.
Is this code under MIT license? I need to know so I can add you in the attributions file.

Thanks,
Oscar.

@magicsih
Copy link
Author

magicsih commented Nov 2, 2019

Hey

It's just an example code. You can use it whatever you want regardless of the license.

Thanks,
Hwan

@ftsfranklin
Copy link

ftsfranklin commented Jan 6, 2022

Warning: Don't use this for real software.

  • RijndaelManaged is discouraged in favor of an AES implementation. (AES is a subset of Rijndael, though.) In particular, use Aes.Create() rather than the AesManaged class or anything else more explicit.
  • RijndaelManaged is not designed to be reused and kept around as a static field.
  • IV should be different and (securely) random for each ciphertext, and stored with it. IV is not a second key, but analogous to the salt in hashing, so it's not secret.
  • Because of the ToString override, it is at risk of exposing the key in log files if the Aes object is logged.

There are probably other issues, but I don't know enough to say. But this gist is publicly visible and appears on Google, so people will stumble onto it and copy it into their code.

@magicsih
Copy link
Author

magicsih commented Jan 6, 2022

Thank you for the reporting. I wrote this code back in 2013 for a sample. What do you think? I was going to delete this gist. On the other hand, I think your comment is anyway helping people to share some wisdom. If they can see it, though.

@ftsfranklin
Copy link

ftsfranklin commented Jan 7, 2022

I'm not sure what's best. If this one disappears, they'll just go somewhere else which might not have warnings (like one of its forks). But they might also go somewhere which has better warnings, and people might not scroll down to see my comment. The code also appears without warnings on the Highly Scalable blog (which I assume is yours).

It's advised not to write cryptography-related code at such a low level that you are choosing the algorithm and configuring it (see [1], [2]), but I haven't found the proper solution myself yet.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment