String Encryption and Decryption Extension
// December 10th, 2009 // Useful Code
This extension is a little longer then usual and it also has a few supporting extensions which are required to make it run; I have included all of which in this post. I wrote a few extras to just make some of the code a little bit shorter and neater. The first is Reverse which like the name implies reverses an incoming string. The second is ToByteArray which converts a string to a Byte Array. The third is ConvertToString which does the exact opposite of ToByteArray by converting a Byte Array back into a string.
//Code
/// <summary>
/// ENCRYPTS A STRING USING AES ENCRYPTION AND A PASSWORD
/// </summary>
/// <param name="s">INCOMING STRING TO ENCRYPT</param>
/// <param name="password">PASSWORD TO USE FOR ENCRYPTION</param>
/// <returns>BASE64 ENCODED ENCRYPTED STRING</returns>
public static string EncryptString(this string s, string password)
{
//CREATE AN AES CRYPTOGRAPHY CLASS
using (Aes tmpAes = AesCryptoServiceProvider.Create())
{
//CREATE A PASSWORD DERIVED BYTES CLASS TO CONVERT A SIMPLE PASSWORD INTO SOMETHING MORE COMPLEX
PasswordDeriveBytes tmpPasswordBytes = new PasswordDeriveBytes(password.ToByteArray(), password.Reverse().ToByteArray());
//CREATE A ICRYPTO TRANSFORM PROVIDER USING 256 BITS FOR THE KEY WHICH IS DERIVED FROM THE PASSWORD PASSED IN
using (ICryptoTransform tmpCrypto = tmpAes.CreateEncryptor(tmpPasswordBytes.GetBytes(256 / 8), tmpPasswordBytes.GetBytes(16)))
{
//CREATE A TEMPORARY MEMORY STREAM TO HOLD THE DATA WHICH IS BEING ENCRYPTED
using (MemoryStream tmpMemoryStream = new MemoryStream())
{
//CREATE THE CRYPTO STREAM WHICH WILL WRITE TO THE UNDERLYING MEMORY STREAM
using (CryptoStream tmpStream = new CryptoStream(tmpMemoryStream, tmpCrypto, CryptoStreamMode.Write))
{
tmpStream.Write(s.ToByteArray(), 0, s.Length);
tmpStream.Flush();
}
//CONVERT THE DATA TO A BASE64 STRING SO WE HAVE ALL VALID CHARACTERS IN THE STRING
return Convert.ToBase64String(tmpMemoryStream.ToArray());
}
}
}
}
/// <summary>
/// DECRYPTS A BASE64 ENCODED STRING USING AES AND PASSWORD
/// </summary>
/// <param name="s">INCOMING BASE64 ENCODED STRING TO DECRYPT</param>
/// <param name="password">PASSWORD USED DURING THE ENCRYPTION PROCESS TO REVERSE THE SEQUENCE</param>
/// <returns>ORIGINAL STRING PRIOR TO ENCRYPTION</returns>
public static string DecryptString(this string s, string password)
{
//CREATE AN AES CRYPTOGRAPHY CLASS
using (Aes tmpAes = AesCryptoServiceProvider.Create())
{
//CREATE A PASSWORD DERIVED BYTES CLASS TO CONVERT A SIMPLE PASSWORD INTO SOMETHING MORE COMPLEX
PasswordDeriveBytes tmpPasswordBytes = new PasswordDeriveBytes(password.ToByteArray(), password.Reverse().ToByteArray());
//CREATE A ICRYPTO TRANSFORM PROVIDER USING 256 BITS FOR THE KEY WHICH IS DERIVED FROM THE PASSWORD PASSED IN
using (ICryptoTransform tmpCrypto = tmpAes.CreateDecryptor(tmpPasswordBytes.GetBytes(256 / 8), tmpPasswordBytes.GetBytes(16)))
{
//CREATE A MEMORY STREAM FROM THE BASE64 STRING WHICH IS BEING PASSED IN
using (MemoryStream tmpMemoryStream = new MemoryStream(Convert.FromBase64String(s)))
{
//CREATE A NEW STREAM WHICH WILL DECRYPT THE DATA AS WE READ IT
using (CryptoStream tmpStream = new CryptoStream(tmpMemoryStream, tmpCrypto, CryptoStreamMode.Read))
{
int readCount;
byte[] tmpBuffer = new byte[1024];
StringBuilder tmpReturn = new StringBuilder();
//CATCH THE ERROR INCASE THE PASSWORD IS INVALID
try
{
//AS LONG AS THEIR IS DATA ON THE STREAM KEEP READING
while ((readCount = tmpStream.Read(tmpBuffer, 0, tmpBuffer.Length)) != 0)
{
tmpReturn.Append(tmpBuffer.Take(readCount).ToArray().ConvertToString());
}
//RETURN THE DECRYPTED STRING VALUE
return tmpReturn.ToString();
}
catch (CryptographicException ex)
{
return "";
}
}
}
}
}
}
#region "Supporting Extensions"
/// <summary>
/// CONVERT AN ARRAY OF BYTES INTO THE UTF8 STRING
/// </summary>
/// <param name="b">ARRAY OF BYTES COMING IN</param>
/// <returns>STRING REPRESENTATION OF THE BYTES PASSED IN</returns>
public static string ConvertToString(this byte[] b)
{
return System.Text.ASCIIEncoding.UTF8.GetString(b);
}
/// <summary>
/// REVERSES A STRING
/// </summary>
/// <param name="s">INCOMING STRING TO REVERSE</param>
/// <returns>REVERSED STRING</returns>
public static string Reverse(this string s)
{
StringBuilder tmpReturn = new StringBuilder();
//LOOP THROUGH EACH CHARACTER FROM BACK TO FRONT AND INSERT IT INTO THE BUILDER
for (int i = s.Length - 1; i >= 0; i--)
tmpReturn.Append(s[i]);
//RETURN THE REVERSED STRING TO THE CALLING FUNCTION
return tmpReturn.ToString();
}
/// <summary>
/// CONVERTS A STRING INTO UTF8 ENCODED BYTE ARRAY
/// </summary>
/// <param name="s">INCOMING STRING TO CONVERT</param>
/// <returns>BYTE ARRAY OF THE INCOMING STRING</returns>
public static byte[] ToByteArray(this string s)
{
//CONVERT THE STRING TO A BYTE ARRAY
return System.Text.ASCIIEncoding.UTF8.GetBytes(s);
}
#endregion
//Usage
class Program
{
static void Main(string[] args)
{
string tmpEnc = "Hello, World!".EncryptString("password");
string tmpDec = tmpEnc.DecryptString("password");
Console.WriteLine("{0}\n{1}", tmpEnc, tmpDec);
Console.ReadLine();
}
}
Leave a Reply
You must be logged in to post a comment.
Michael E. Chancey Jr. Software Engineer Extraordinaire