Encryption / Cryptography
RijndaelManaged
Section titled “RijndaelManaged”Required Namespace: System.Security.Cryptography
private class Encryption {
private const string SecretKey = "topSecretKeyusedforEncryptions";
private const string SecretIv = "secretVectorHere";
public string Encrypt(string data) { return string.IsNullOrEmpty(data) ? data : Convert.ToBase64String(this.EncryptStringToBytesAes(data, this.GetCryptographyKey(), this.GetCryptographyIv())); }
public string Decrypt(string data) { return string.IsNullOrEmpty(data) ? data : this.DecryptStringFromBytesAes(Convert.FromBase64String(data), this.GetCryptographyKey(), this.GetCryptographyIv()); }
private byte[] GetCryptographyKey() { return Encoding.ASCII.GetBytes(SecretKey.Replace('e', '!')); }
private byte[] GetCryptographyIv() { return Encoding.ASCII.GetBytes(SecretIv.Replace('r', '!')); }
private byte[] EncryptStringToBytesAes(string plainText, byte[] key, byte[] iv) { MemoryStream encrypt; RijndaelManaged aesAlg = null; try { aesAlg = new RijndaelManaged { Key = key, IV = iv }; var encryptor = aesAlg.CreateEncryptor(aesAlg.Key, aesAlg.IV); encrypt = new MemoryStream(); using (var csEncrypt = new CryptoStream(encrypt, encryptor, CryptoStreamMode.Write)) { using (var swEncrypt = new StreamWriter(csEncrypt)) { swEncrypt.Write(plainText); } } } finally { aesAlg?.Clear(); } return encrypt.ToArray(); }
private string DecryptStringFromBytesAes(byte[] cipherText, byte[] key, byte[] iv) { RijndaelManaged aesAlg = null; string plaintext; try { aesAlg = new RijndaelManaged { Key = key, IV = iv }; var decryptor = aesAlg.CreateDecryptor(aesAlg.Key, aesAlg.IV); using (var msDecrypt = new MemoryStream(cipherText)) { using (var csDecrypt = new CryptoStream(msDecrypt, decryptor, CryptoStreamMode.Read)) { using (var srDecrypt = new StreamReader(csDecrypt)) plaintext = srDecrypt.ReadToEnd(); } } } finally { aesAlg?.Clear(); } return plaintext; } }Usage
var textToEncrypt = "hello World";
var encrypted = new Encryption().Encrypt(textToEncrypt); //-> zBmW+FUxOvdbpOGm9Ss/vQ==
var decrypted = new Encryption().Decrypt(encrypted); //-> hello WorldNote:
- Rijndael is the predecessor of the standard symmetric cryptographic algorithm AES.
Encrypt and decrypt data using AES (in C#)
Section titled “Encrypt and decrypt data using AES (in C#)”using System;using System.IO;using System.Security.Cryptography;
namespace Aes_Example{ class AesExample { public static void Main() { try { string original = "Here is some data to encrypt!";
// Create a new instance of the Aes class. // This generates a new key and initialization vector (IV). using (Aes myAes = Aes.Create()) { // Encrypt the string to an array of bytes. byte[] encrypted = EncryptStringToBytes_Aes(original, myAes.Key, myAes.IV);
// Decrypt the bytes to a string. string roundtrip = DecryptStringFromBytes_Aes(encrypted, myAes.Key, myAes.IV);
//Display the original data and the decrypted data. Console.WriteLine("Original: {0}", original); Console.WriteLine("Round Trip: {0}", roundtrip); } } catch (Exception e) { Console.WriteLine("Error: {0}", e.Message); } }
static byte[] EncryptStringToBytes_Aes(string plainText, byte[] Key, byte[] IV) { // Check arguments. if (plainText == null || plainText.Length <= 0) throw new ArgumentNullException("plainText"); if (Key == null || Key.Length <= 0) throw new ArgumentNullException("Key"); if (IV == null || IV.Length <= 0) throw new ArgumentNullException("IV");
byte[] encrypted;
// Create an Aes object with the specified key and IV. using (Aes aesAlg = Aes.Create()) { aesAlg.Key = Key; aesAlg.IV = IV;
// Create a decrytor to perform the stream transform. ICryptoTransform encryptor = aesAlg.CreateEncryptor(aesAlg.Key, aesAlg.IV);
// Create the streams used for encryption. using (MemoryStream msEncrypt = new MemoryStream()) { using (CryptoStream csEncrypt = new CryptoStream(msEncrypt, encryptor, CryptoStreamMode.Write)) { using (StreamWriter swEncrypt = new StreamWriter(csEncrypt)) { //Write all data to the stream. swEncrypt.Write(plainText); }
encrypted = msEncrypt.ToArray(); } } }
// Return the encrypted bytes from the memory stream. return encrypted; }
static string DecryptStringFromBytes_Aes(byte[] cipherText, byte[] Key, byte[] IV) { // Check arguments. if (cipherText == null || cipherText.Length <= 0) throw new ArgumentNullException("cipherText"); if (Key == null || Key.Length <= 0) throw new ArgumentNullException("Key"); if (IV == null || IV.Length <= 0) throw new ArgumentNullException("IV");
// Declare the string used to hold the decrypted text. string plaintext = null;
// Create an Aes object with the specified key and IV. using (Aes aesAlg = Aes.Create()) { aesAlg.Key = Key; aesAlg.IV = IV;
// Create a decrytor to perform the stream transform. ICryptoTransform decryptor = aesAlg.CreateDecryptor(aesAlg.Key, aesAlg.IV);
// Create the streams used for decryption. using (MemoryStream msDecrypt = new MemoryStream(cipherText)) { using (CryptoStream csDecrypt = new CryptoStream(msDecrypt, decryptor, CryptoStreamMode.Read)) { using (StreamReader srDecrypt = new StreamReader(csDecrypt)) {
// Read the decrypted bytes from the decrypting stream // and place them in a string. plaintext = srDecrypt.ReadToEnd(); } } } }
return plaintext; } }}This example is from MSDN.
It is a console demo application, showing how to encrypt a string by using the standard AES encryption, and how to decrypt it afterwards.
(AES = Advanced Encryption Standard, a specification for the encryption of electronic data established by the U.S. National Institute of Standards and Technology (NIST) in 2001 which is still the de-facto standard for symmetric encryption)
Notes:
Usage: see Main() method.
Create a Key from a Password / Random SALT (in C#)
Section titled “Create a Key from a Password / Random SALT (in C#)”using System;using System.Security.Cryptography;using System.Text;
public class PasswordDerivedBytesExample{ public static void Main(String[] args) { // Get a password from the user. Console.WriteLine("Enter a password to produce a key:");
byte[] pwd = Encoding.Unicode.GetBytes(Console.ReadLine());
byte[] salt = CreateRandomSalt(7);
// Create a TripleDESCryptoServiceProvider object. TripleDESCryptoServiceProvider tdes = new TripleDESCryptoServiceProvider();
try { Console.WriteLine("Creating a key with PasswordDeriveBytes...");
// Create a PasswordDeriveBytes object and then create // a TripleDES key from the password and salt. PasswordDeriveBytes pdb = new PasswordDeriveBytes(pwd, salt);
// Create the key and set it to the Key property // of the TripleDESCryptoServiceProvider object. tdes.Key = pdb.CryptDeriveKey("TripleDES", "SHA1", 192, tdes.IV);
Console.WriteLine("Operation complete."); } catch (Exception e) { Console.WriteLine(e.Message); } finally { // Clear the buffers ClearBytes(pwd); ClearBytes(salt);
// Clear the key. tdes.Clear(); }
Console.ReadLine(); }
#region Helper methods
/// <summary> /// Generates a random salt value of the specified length. /// </summary> public static byte[] CreateRandomSalt(int length) { // Create a buffer byte[] randBytes;
if (length >= 1) { randBytes = new byte[length]; } else { randBytes = new byte[1]; }
// Create a new RNGCryptoServiceProvider. RNGCryptoServiceProvider rand = new RNGCryptoServiceProvider();
// Fill the buffer with random bytes. rand.GetBytes(randBytes);
// return the bytes. return randBytes; }
/// <summary> /// Clear the bytes in a buffer so they can't later be read from memory. /// </summary> public static void ClearBytes(byte[] buffer) { // Check arguments. if (buffer == null) { throw new ArgumentNullException("buffer"); }
// Set each byte in the buffer to 0. for (int x = 0; x < buffer.Length; x++) { buffer[x] = 0; } }
#endregion}This example is taken from MSDN.
It is a console demo, and it shows how to create a secure key based on a user-defined password, and how to create a random SALT based on the cryptographic random generator.
Notes:
**NOTE:** As a workaround, you can create a random AES key for encryption of the data to be protected with AES and store the AES key in a TripleDES-Container which uses the key generated by `CryptDeriveKey`. But that limits the security to TripleDES, does not take advantage of the larger keysizes of AES and creates a dependency to TripleDES.
Usage: See Main() method.
Encryption and Decryption using Cryptography (AES)
Section titled “Encryption and Decryption using Cryptography (AES)”Decryption Code
public static string Decrypt(string cipherText) { if (cipherText == null) return null;
byte[] cipherBytes = Convert.FromBase64String(cipherText); using (Aes encryptor = Aes.Create()) { Rfc2898DeriveBytes pdb = new Rfc2898DeriveBytes(CryptKey, new byte[] { 0x49, 0x76, 0x61, 0x6e, 0x20, 0x4d, 0x65, 0x64, 0x76, 0x65, 0x64, 0x65, 0x76 }); encryptor.Key = pdb.GetBytes(32); encryptor.IV = pdb.GetBytes(16);
using (MemoryStream ms = new MemoryStream()) { using (CryptoStream cs = new CryptoStream(ms, encryptor.CreateDecryptor(), CryptoStreamMode.Write)) { cs.Write(cipherBytes, 0, cipherBytes.Length); cs.Close(); }
cipherText = Encoding.Unicode.GetString(ms.ToArray()); } }
return cipherText; }Encryption Code
public static string Encrypt(string cipherText) { if (cipherText == null) return null;
byte[] clearBytes = Encoding.Unicode.GetBytes(cipherText); using (Aes encryptor = Aes.Create()) { Rfc2898DeriveBytes pdb = new Rfc2898DeriveBytes(CryptKey, new byte[] { 0x49, 0x76, 0x61, 0x6e, 0x20, 0x4d, 0x65, 0x64, 0x76, 0x65, 0x64, 0x65, 0x76 }); encryptor.Key = pdb.GetBytes(32); encryptor.IV = pdb.GetBytes(16);
using (MemoryStream ms = new MemoryStream()) { using (CryptoStream cs = new CryptoStream(ms, encryptor.CreateEncryptor(), CryptoStreamMode.Write)) { cs.Write(clearBytes, 0, clearBytes.Length); cs.Close(); }
cipherText = Convert.ToBase64String(ms.ToArray()); } } return cipherText; }Usage
var textToEncrypt = "TestEncrypt";
var encrypted = Encrypt(textToEncrypt);
var decrypted = Decrypt(encrypted);Remarks
Section titled “Remarks”.NET Framework provides implementation of many cryptographic algorithms. They include basically symmetric algorithms, asymmetric algorithms and hashes.