Encryption and Decryption of content using RijndaelManaged Class in C#

If you want to encrypt and decrypt data in your .NET application then one of the most simplest and safest way is using RijndaelManaged class.

It is predecessor of Aes but still most of the new users us RijndaelManaged class because it is easy to plug and use.

First we have to generate an encryption key using a password ans salt. Password and salt could be any string (use base64 string to make your encryption stronger) which we have to convert to bytes array (byte[]) before using them for generating encryption key. Below is the complete example of generating key and encryption and decryption

public static byte[] GenerateEncryptionKey(string password, string saltString)
{
	byte[] salt = Convert.FromBase64String(saltString);
	var keyGen = new Rfc2898DeriveBytes(password, salt, 7845);
	return keyGen.GetBytes(32);
}
public static string Encrypt(object data, string password, string saltString)
{
	try
	{
		using (var aes = new RijndaelManaged())
		{
			//get some bytes
			aes.Key = GenerateEncryptionKey(password, saltString);
			aes.BlockSize = 256;
			aes.Padding = PaddingMode.PKCS7;

			//generate an IV
			aes.GenerateIV();

			//get the bytes for our message
			var plainBytes = Encoding.UTF8.GetBytes(data.ToString());

			//start up the encryption
			using (var ms = new MemoryStream())
			using (var cs = new CryptoStream(ms, aes.CreateEncryptor(), CryptoStreamMode.Write))
			{
				//write the bytes to the cryptostream
				cs.Write(plainBytes, 0, plainBytes.Length);
				cs.FlushFinalBlock();

				//get message bytes
				var msgBytes = ms.ToArray();

				//create a new array big enough for the both of 'em
				var cypherBytes = new byte[aes.IV.Length + msgBytes.Length];

				//return the string with the iv as the first 32 bytes. will need this when decrypting
				System.Buffer.BlockCopy(aes.IV, 0, cypherBytes, 0, aes.IV.Length);
				System.Buffer.BlockCopy(msgBytes, 0, cypherBytes, aes.IV.Length, msgBytes.Length);

				//now convert it to base64 string
				var cypherText = System.Convert.ToBase64String(cypherBytes).TrimEnd(new char[] { '=' }).Replace('+', '-').Replace('/', '_');
				//var cypherText = Convert.ToBase64String(cypherBytes);

				//return cypher text
				return cypherText;
			}
		}
	}
	catch (Exception)
	{
		return null;
	}
}

public static string Decrypt(object cypherData, string password, string saltString)
{
	try
	{
		using (var aes = new RijndaelManaged())
		{
			//get some bytes
			aes.Key = GenerateEncryptionKey(password, saltString);
			aes.BlockSize = 256;
			aes.Padding = PaddingMode.PKCS7;

			//get the bytes for our message
			string cypherStr = cypherData.ToString();
			string incoming = cypherStr.Replace('_', '/').Replace('-', '+');
			switch (cypherStr.Length % 4)
			{
				case 2: incoming += "=="; break;
				case 3: incoming += "="; break;
			}
			
			var cypherBytes = Convert.FromBase64String(incoming);
			//var cypherBytes = Convert.FromBase64String(cypherData.ToString());
			var iv = new byte[aes.IV.Length];
			var msgBytes = new byte[cypherBytes.Length - iv.Length];

			//we use the first 32 bytes of the cypherdata for the IV
			System.Buffer.BlockCopy(cypherBytes, 0, iv, 0, iv.Length);
			System.Buffer.BlockCopy(cypherBytes, iv.Length, msgBytes, 0, msgBytes.Length);

			//set the IV for the instance
			aes.IV = iv;

			//start up the decryption
			using (var ms = new MemoryStream())
			using (var cs = new CryptoStream(ms, aes.CreateDecryptor(), CryptoStreamMode.Write))
			{
				//write the bytes to the cryptostream
				cs.Write(msgBytes, 0, msgBytes.Length);
				cs.FlushFinalBlock();
					  
				//the plain text has been decrypted.
				var plainText = System.Text.Encoding.UTF8.GetString(ms.ToArray());

				//return plain text
				return plainText;
			}
		 }
	}
	catch (Exception)
	{
		return null;
	}
}

Leave a Reply

Your email address will not be published.