RijndaelEncryptor.cs
1 using System;
2 using System.Collections.Generic;
3 using System.Linq;
4 using System.Text;
5 using System.Security.Cryptography;
6 using System.IO;
7 
8 namespace Encryptor
9 {
10  public static partial class StringEncryptor
11  {
12  //private static string passPhrase = "S@gEseCuriTY.2k12.Pa@spHRASe"; // can be any string
13  //private static string saltValue = "S@gEseCuriTY.2k12.s@1tValue"; // can be any string
14  //private static string hashAlgorithm = "SHA1"; // can be "MD5"
15  //private static int passwordIterations = 2; // can be any number
16  //private static string initVector = "@1B2c3D4e5F6g7H8"; // must be 16 bytes
17  //private static int keySize = 256; // can be 192 or 128
18 
19  //public static string Encrypt(string plainText)
20  //{
21  // return Encrypt(plainText, passPhrase, saltValue, hashAlgorithm, passwordIterations, initVector, keySize);
22  //}
23 
61  public static string Encrypt(string plainText,
62  string passPhrase,
63  string saltValue,
64  string hashAlgorithm,
65  int passwordIterations,
66  string initVector,
67  int keySize)
68  {
69  // Convert strings into byte arrays.
70  // Let us assume that strings only contain ASCII codes.
71  // If strings include Unicode characters, use Unicode, UTF7, or UTF8
72  // encoding.
73  byte[] initVectorBytes = Encoding.ASCII.GetBytes(initVector);
74  byte[] saltValueBytes = Encoding.ASCII.GetBytes(saltValue);
75 
76  // Convert our plaintext into a byte array.
77  // Let us assume that plaintext contains UTF8-encoded characters.
78  byte[] plainTextBytes = Encoding.UTF8.GetBytes(plainText);
79 
80  // First, we must create a password, from which the key will be derived.
81  // This password will be generated from the specified passphrase and
82  // salt value. The password will be created using the specified hash
83  // algorithm. Password creation can be done in several iterations.
84  PasswordDeriveBytes password = new PasswordDeriveBytes(
85  passPhrase,
86  saltValueBytes,
87  hashAlgorithm,
88  passwordIterations);
89 
90  // Use the password to generate pseudo-random bytes for the encryption
91  // key. Specify the size of the key in bytes (instead of bits).
92  byte[] keyBytes = password.GetBytes(keySize / 8);
93 
94  // Create uninitialized Rijndael encryption object.
95  RijndaelManaged symmetricKey = new RijndaelManaged();
96 
97  // It is reasonable to set encryption mode to Cipher Block Chaining
98  // (CBC). Use default options for other symmetric key parameters.
99  symmetricKey.Mode = CipherMode.CBC;
100 
101  // Generate encryptor from the existing key bytes and initialization
102  // vector. Key size will be defined based on the number of the key
103  // bytes.
104  ICryptoTransform encryptor = symmetricKey.CreateEncryptor(
105  keyBytes,
106  initVectorBytes);
107 
108  // Define memory stream which will be used to hold encrypted data.
109  MemoryStream memoryStream = new MemoryStream();
110 
111  // Define cryptographic stream (always use Write mode for encryption).
112  CryptoStream cryptoStream = new CryptoStream(memoryStream,
113  encryptor,
114  CryptoStreamMode.Write);
115  // Start encrypting.
116  cryptoStream.Write(plainTextBytes, 0, plainTextBytes.Length);
117 
118  // Finish encrypting.
119  cryptoStream.FlushFinalBlock();
120 
121  // Convert our encrypted data from a memory stream into a byte array.
122  byte[] cipherTextBytes = memoryStream.ToArray();
123 
124  // Close both streams.
125  memoryStream.Close();
126  cryptoStream.Close();
127 
128  // Convert encrypted data into a base64-encoded string.
129  string cipherText = Convert.ToBase64String(cipherTextBytes);
130 
131  // Return encrypted string.
132  return cipherText;
133  }
134 
178  public static string Decrypt(string cipherText,
179  string passPhrase,
180  string saltValue,
181  string hashAlgorithm,
182  int passwordIterations,
183  string initVector,
184  int keySize)
185  {
186  // Convert strings defining encryption key characteristics into byte
187  // arrays. Let us assume that strings only contain ASCII codes.
188  // If strings include Unicode characters, use Unicode, UTF7, or UTF8
189  // encoding.
190  byte[] initVectorBytes = Encoding.ASCII.GetBytes(initVector);
191  byte[] saltValueBytes = Encoding.ASCII.GetBytes(saltValue);
192 
193  // Convert our ciphertext into a byte array.
194  byte[] cipherTextBytes = Convert.FromBase64String(cipherText);
195 
196  // First, we must create a password, from which the key will be
197  // derived. This password will be generated from the specified
198  // passphrase and salt value. The password will be created using
199  // the specified hash algorithm. Password creation can be done in
200  // several iterations.
201  PasswordDeriveBytes password = new PasswordDeriveBytes(
202  passPhrase,
203  saltValueBytes,
204  hashAlgorithm,
205  passwordIterations);
206 
207  // Use the password to generate pseudo-random bytes for the encryption
208  // key. Specify the size of the key in bytes (instead of bits).
209  byte[] keyBytes = password.GetBytes(keySize / 8);
210 
211  // Create uninitialized Rijndael encryption object.
212  RijndaelManaged symmetricKey = new RijndaelManaged();
213 
214  // It is reasonable to set encryption mode to Cipher Block Chaining
215  // (CBC). Use default options for other symmetric key parameters.
216  symmetricKey.Mode = CipherMode.CBC;
217 
218  // Generate decryptor from the existing key bytes and initialization
219  // vector. Key size will be defined based on the number of the key
220  // bytes.
221  ICryptoTransform decryptor = symmetricKey.CreateDecryptor(
222  keyBytes,
223  initVectorBytes);
224 
225  // Define memory stream which will be used to hold encrypted data.
226  MemoryStream memoryStream = new MemoryStream(cipherTextBytes);
227 
228  // Define cryptographic stream (always use Read mode for encryption).
229  CryptoStream cryptoStream = new CryptoStream(memoryStream,
230  decryptor,
231  CryptoStreamMode.Read);
232 
233  // Since at this point we don't know what the size of decrypted data
234  // will be, allocate the buffer long enough to hold ciphertext;
235  // plaintext is never longer than ciphertext.
236  byte[] plainTextBytes = new byte[cipherTextBytes.Length];
237 
238  // Start decrypting.
239  int decryptedByteCount = cryptoStream.Read(plainTextBytes,
240  0,
241  plainTextBytes.Length);
242 
243  // Close both streams.
244  memoryStream.Close();
245  cryptoStream.Close();
246 
247  // Convert decrypted data into a string.
248  // Let us assume that the original plaintext string was UTF8-encoded.
249  string plainText = Encoding.UTF8.GetString(plainTextBytes,
250  0,
251  decryptedByteCount);
252 
253  // Return decrypted string.
254  return plainText;
255  }
256  }
257 }