1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84
// ***** Encryption and Decryption ***** // byte[] Key(string sText) { if (Encoding.Default.GetBytes(sText).Length > 32) { throw new ArgumentException("Key must be less than 32 bytes long."); } if (Encoding.Default.GetBytes(sText).Length < 1) { throw new ArgumentException("Key must be more than 0 bytes long."); } while (Encoding.Default.GetBytes(sText).Length < 32) { sText = sText + " "; } return Encoding.Default.GetBytes(sText); } string Encrypt(string sText) { // Convert Input Text into Bytes Array byte[] bText = Encoding.Default.GetBytes(sText.Trim()); // For storing encrypted bytes MemoryStream mStream = new MemoryStream(); // get the algorithm to use SymmetricAlgorithm alg = SymmetricAlgorithm.Create("Rijndael"); // Specify Block and Key Size alg.BlockSize = 256; alg.KeySize = 256; // Create our own Key and IV byte[] key = Key("34553513543651433545343545789341"); byte[] iv = {1,5,6,7,8,1,3,4,5,7,8,9,2,4,5,6,4,5,6,2,4,5,6,4,6,4,2,3,4,8,6,2}; ICryptoTransform encryptor = alg.CreateEncryptor(key, iv); //CreateEncryptor(Byte[] rgbKey, Byte[] rgbIV) // Tell the crypto stream where and how to encrypt CryptoStream crypto = new CryptoStream(mStream, encryptor, CryptoStreamMode.Write); // Do the actually encryption crypto.Write(bText, 0, bText.Length); crypto.Close(); // Byte array with encrypted data byte[] cipher = mStream.ToArray(); // Return Encrypted Text return Convert.ToBase64String(cipher); } string Decrypt(string sText) { // Convert Input Text into Bytes Array byte[] bText = Convert.FromBase64String(sText); // For storing encrypted bytes MemoryStream mStream = new MemoryStream(bText); // get the algorithm to use SymmetricAlgorithm alg = SymmetricAlgorithm.Create("Rijndael"); // Specify Block and Key Size alg.BlockSize = 256; alg.KeySize = 256; // Create our own Key and IV byte[] key = Key("34953913543651433549343595789391"); byte[] iv = {1,5,6,7,9,1,3,4,5,7,8,9,2,4,9,6,4,5,6,2,4,5,6,4,6,4,2,9,4,8,6,2}; ICryptoTransform decryptor = alg.CreateDecryptor(key, iv); //CreateDecryptor(Byte[] rgbKey, Byte[] rgbIV) // Tell the crypto stream where and how to decrypt CryptoStream crypto = new CryptoStream(mStream, decryptor, CryptoStreamMode.Read); // Do the actually decryption byte[] bOutput = new byte[bText.Length - 1 + 1]; crypto.Read(bOutput, 0, bText.Length); crypto.Close(); // Return Decrypted Text return Encoding.Default.GetString(bOutput).Replace("\x000", String.Empty); }
Refactorings
No refactoring yet !
Jonathan Starr
June 22, 2008, June 22, 2008 03:06, permalink
Let me know what you think,
Jonathan
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96
using System; using System.Configuration; using System.IO; using System.Security.Cryptography; using System.Text; namespace Starr { // ***** Encryption and Decryption ***** // internal static class CryptoHelper { private static SymmetricAlgorithm algorithm; private static byte[] key; private static byte[] initialVector; private static byte[] Key(string keyName) { int keyLength = Encoding.Default.GetBytes(keyName).Length; if (keyLength > 32) throw new ArgumentException("Key must be less than 32 bytes long."); if (keyLength < 1) throw new ArgumentException("Key must be more than 0 bytes long."); return Encoding.Default.GetBytes(String.Format("{0,-32}", keyName)); } public static String Encrypt(String textToEncrypt) { Byte[] bytesToEncrypt = Encoding.Default.GetBytes(textToEncrypt.Trim()); MemoryStream mStream = new MemoryStream(); SetAlgorithm(); SetKeyAndInitialVector(CryptoOperation.Encrypt); ICryptoTransform encryptor = algorithm.CreateEncryptor(key, initialVector); using (CryptoStream crypto = new CryptoStream(mStream, encryptor, CryptoStreamMode.Write)) { crypto.Write(bytesToEncrypt, 0, bytesToEncrypt.Length); } return Convert.ToBase64String(mStream.ToArray()); } // Set the encryption/decryption algorithm private static void SetAlgorithm() { algorithm = SymmetricAlgorithm.Create("Rijndael"); algorithm.BlockSize = 256; algorithm.KeySize = 256; } public static String Decrypt(string textToDecrypt) { Byte[] bytesToDecrypt = Convert.FromBase64String(textToDecrypt); MemoryStream mStream = new MemoryStream(bytesToDecrypt); SetAlgorithm(); SetKeyAndInitialVector(CryptoOperation.Decrypt); ICryptoTransform decryptor = algorithm.CreateDecryptor(key, initialVector); Byte[] bytesOutput; using (CryptoStream crypto = new CryptoStream(mStream, decryptor, CryptoStreamMode.Read)) { bytesOutput = new Byte[bytesToDecrypt.Length]; crypto.Read(bytesOutput, 0, bytesToDecrypt.Length); } return Encoding.Default.GetString(bytesOutput).Replace("\x000", String.Empty); } private static void SetKeyAndInitialVector(CryptoOperation operation) { key = Key(ConfigurationManager.AppSettings[String.Format("{0}Key", operation)]); initialVector = ArrayConverter.ConvertToBytes(ConfigurationManager.AppSettings[String.Format("{0}InitialVector", operation)].ToCharArray()); } } internal enum CryptoOperation { Encrypt = 0, Decrypt = 1, } internal static class ArrayConverter { internal static Byte [] ConvertToBytes(Char [] inputArray) { Byte [] resultArray = new Byte[inputArray.Length]; for(int index =0; index < inputArray.Length; index++) { resultArray[index] = Byte.Parse(inputArray[index].ToString()); } return resultArray; } } }
Mark Brackett
June 28, 2008, June 28, 2008 06:07, permalink
It's a little odd why you'd have 2 sets of keys - that means your class can't decrypt what it encrypts. Normally, I'd have a constructor that takes in key and iv and keep them as member variables. But, assuming you want that....
Depending on your use case, you may want to make some parts static or member variables (key, iv, algorithm, encryptor, decryptor, etc.) - though you'd then need to implement IDisposable yourself (for the algorithm).
I made KEY_SIZE a const since it's referenced everywhere, and you may want to change it.
Decrypt is virtually the same as Encrypt, so I think you can imagine what it'd look like. ;)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41
const int KEY_SIZE = 32; // Create our own Key and IV readonly byte[] ENCRYPT_KEY = Key("34553513543651433545343545789341"); readonly byte[] ENCRYPT_IV = {1,5,6,7,8,1,3,4,5,7,8,9,2,4,5,6,4,5,6,2,4,5,6,4,6,4,2,3,4,8,6,2}; Key(string sText) { int keyLength = Encoding.Default.GetByteCount(sText); // quicker than converting to byte[] just to get length if (keyLength < 1 || keyLength > KEY_SIZE) { throw new ArgumentException("Key must be more than 0 and less than " + KEY_SIZE + " bytes long."); } if (keyLength < KEY_SIZE) { sText = sText.PadRight(KEY_SIZE); // the method you had would allocate 31 strings if sText == " " } return Encoding.Default.GetBytes(sText); } string Encrypt(string sText) { // Convert Input Text into Bytes Array byte[] bText = Encoding.Default.GetBytes(sText.Trim()); // get the algorithm to use using (SymmetricAlgorithm alg = SymmetricAlgorithm.Create("Rijndael")) { // Specify Block and Key Size alg.BlockSize = 256; alg.KeySize = KEY_SIZE * 8; // IDisposables always go in using blocks.... using (MemoryStream mStream = new MemoryStream()) using (CryptoStream crypto = new CryptoStream(mStream, alg.CreateEncryptor(ENCRYPT_KEY, ENCRYPT_IV), CryptoStreamMode.Write)) { // Do the actual encryption crypto.Write(bText, 0, bText.Length); crypto.Close(); // Return Encrypted Text return Convert.ToBase64String(mStream.ToArray()); } } }
This is my first attempt at Encryption and Decryption functions and I would love your feedback. :)
key and iv are your "passwords" and should be changed.
Many Thanks
Stephen