Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- using System;
- using System.Security.Cryptography;
- using System.Text;
- class AesDemo {
- const int HASH_SIZE = 32; //SHA256
- /// <summary>Performs encryption with random IV (prepended to output), and includes hash of plaintext for verification.</summary>
- public static byte[] Encrypt(string password, byte[] passwordSalt, byte[] plainText) {
- // Construct message with hash
- var msg = new byte[HASH_SIZE + plainText.Length];
- var hash = computeHash(plainText, 0, plainText.Length);
- Buffer.BlockCopy(hash, 0, msg, 0, HASH_SIZE);
- Buffer.BlockCopy(plainText, 0, msg, HASH_SIZE, plainText.Length);
- // Encrypt
- using (var aes = createAes(password, passwordSalt)) {
- aes.GenerateIV();
- using (var enc = aes.CreateEncryptor()) {
- var encBytes = enc.TransformFinalBlock(msg, 0, msg.Length);
- // Prepend IV to result
- var res = new byte[aes.IV.Length + encBytes.Length];
- Buffer.BlockCopy(aes.IV, 0, res, 0, aes.IV.Length);
- Buffer.BlockCopy(encBytes, 0, res, aes.IV.Length, encBytes.Length);
- return res;
- }
- }
- }
- public static byte[] Decrypt(string password, byte[] passwordSalt, byte[] cipherText) {
- using (var aes = createAes(password, passwordSalt)) {
- var iv = new byte[aes.IV.Length];
- Buffer.BlockCopy(cipherText, 0, iv, 0, iv.Length);
- aes.IV = iv; // Probably could copy right to the byte array, but that's not guaranteed
- using (var dec = aes.CreateDecryptor()) {
- var decBytes = dec.TransformFinalBlock(cipherText, iv.Length, cipherText.Length - iv.Length);
- // Verify hash
- var hash = computeHash(decBytes, HASH_SIZE, decBytes.Length - HASH_SIZE);
- var existingHash = new byte[HASH_SIZE];
- Buffer.BlockCopy(decBytes, 0, existingHash, 0, HASH_SIZE);
- if (!compareBytes(existingHash, hash)){
- throw new CryptographicException("Message hash incorrect.");
- }
- // Hash is valid, we're done
- var res = new byte[decBytes.Length - HASH_SIZE];
- Buffer.BlockCopy(decBytes, HASH_SIZE, res, 0, res.Length);
- return res;
- }
- }
- }
- static bool compareBytes(byte[] a1, byte[] a2) {
- if (a1.Length != a2.Length) return false;
- for (int i = 0; i < a1.Length; i++) {
- if (a1[i] != a2[i]) return false;
- }
- return true;
- }
- static Aes createAes(string password, byte[] salt) {
- // Salt may not be needed if password is safe
- if (password.Length < 8) throw new ArgumentException("Password must be at least 8 characters.", "password");
- if (salt.Length < 8) throw new ArgumentException("Salt must be at least 8 bytes.", "salt");
- var pdb = new PasswordDeriveBytes(password, salt, "SHA512", 129);
- var key = pdb.GetBytes(16);
- var aes = Aes.Create();
- aes.Mode = CipherMode.CBC;
- aes.Key = pdb.GetBytes(aes.KeySize / 8);
- return aes;
- }
- static byte[] computeHash(byte[] data, int offset, int count) {
- using (var sha = SHA256.Create()) {
- return sha.ComputeHash(data, offset, count);
- }
- }
- public static void Main() {
- var password = "1234567890!";
- var salt = new byte[] { 1, 2, 3, 4, 5, 6, 7, 8, 9, 0 };
- var ct1 = Encrypt(password, salt, Encoding.UTF8.GetBytes("Alice; Bob; Eve;: PerformAct1"));
- Console.WriteLine(Convert.ToBase64String(ct1));
- var ct2 = Encrypt(password, salt, Encoding.UTF8.GetBytes("Alice; Bob; Eve;: PerformAct2"));
- Console.WriteLine(Convert.ToBase64String(ct2));
- var pt1 = Decrypt(password, salt, ct1);
- Console.WriteLine(Encoding.UTF8.GetString(pt1));
- var pt2 = Decrypt(password, salt, ct2);
- Console.WriteLine(Encoding.UTF8.GetString(pt2));
- // Now check tampering
- try {
- ct1[30]++;
- Decrypt(password, salt, ct1);
- Console.WriteLine("Error: tamper detection failed.");
- } catch (Exception ex) {
- Console.WriteLine("Success: tampering detected.");
- Console.WriteLine(ex.ToString());
- }
- }
- }
- public static void Main() {
- var buff = new byte[8];
- new Random().NextBytes(buff);
- var v = BitConverter.ToUInt64(buff, 0);
- Console.WriteLine("Value: " + v.ToString());
- Console.WriteLine("Value (bytes): " + BitConverter.ToString(BitConverter.GetBytes(v)));
- var aes = Aes.Create();
- aes.GenerateIV();
- aes.GenerateKey();
- var encBytes = aes.CreateEncryptor().TransformFinalBlock(BitConverter.GetBytes(v), 0, 8);
- Console.WriteLine("Encrypted: " + BitConverter.ToString(encBytes));
- var dec = aes.CreateDecryptor();
- Console.WriteLine("Decrypted: " + BitConverter.ToUInt64(dec.TransformFinalBlock(encBytes, 0, encBytes.Length), 0));
- for (int i = 0; i < 8; i++) {
- for (int x = 0; x < 250; x++) {
- encBytes[i]++;
- try {
- Console.WriteLine("Attacked: " + BitConverter.ToUInt64(dec.TransformFinalBlock(encBytes, 0, encBytes.Length), 0));
- return;
- } catch { }
- }
- }
- }
- using System;
- using System.Data;
- using System.Security.Cryptography;
- using System.IO;
- public class SimpleAES
- {
- // Change these keys
- private byte[] Key = { 123, 217, 19, 11, 24, 26, 85, 45, 114, 184, 27, 162, 37, 112, 222, 209, 241, 24, 175, 144, 173, 53, 196, 29, 24, 26, 17, 218, 131, 236, 53, 209 };
- private byte[] Vector = { 146, 64, 191, 111, 23, 3, 113, 119, 231, 121, 2521, 112, 79, 32, 114, 156 };
- private ICryptoTransform EncryptorTransform, DecryptorTransform;
- private System.Text.UTF8Encoding UTFEncoder;
- public SimpleAES()
- {
- //This is our encryption method
- RijndaelManaged rm = new RijndaelManaged();
- //Create an encryptor and a decryptor using our encryption method, key, and vector.
- EncryptorTransform = rm.CreateEncryptor(this.Key, this.Vector);
- DecryptorTransform = rm.CreateDecryptor(this.Key, this.Vector);
- //Used to translate bytes to text and vice versa
- UTFEncoder = new System.Text.UTF8Encoding();
- }
- /// -------------- Two Utility Methods (not used but may be useful) -----------
- /// Generates an encryption key.
- static public byte[] GenerateEncryptionKey()
- {
- //Generate a Key.
- RijndaelManaged rm = new RijndaelManaged();
- rm.GenerateKey();
- return rm.Key;
- }
- /// Generates a unique encryption vector
- static public byte[] GenerateEncryptionVector()
- {
- //Generate a Vector
- RijndaelManaged rm = new RijndaelManaged();
- rm.GenerateIV();
- return rm.IV;
- }
- /// ----------- The commonly used methods ------------------------------
- /// Encrypt some text and return a string suitable for passing in a URL.
- public string EncryptToString(string TextValue)
- {
- return ByteArrToString(Encrypt(TextValue));
- }
- /// Encrypt some text and return an encrypted byte array.
- public byte[] Encrypt(string TextValue)
- {
- //Translates our text value into a byte array.
- Byte[] bytes = UTFEncoder.GetBytes(TextValue);
- //Used to stream the data in and out of the CryptoStream.
- MemoryStream memoryStream = new MemoryStream();
- /*
- * We will have to write the unencrypted bytes to the stream,
- * then read the encrypted result back from the stream.
- */
- #region Write the decrypted value to the encryption stream
- CryptoStream cs = new CryptoStream(memoryStream, EncryptorTransform, CryptoStreamMode.Write);
- cs.Write(bytes, 0, bytes.Length);
- cs.FlushFinalBlock();
- #endregion
- #region Read encrypted value back out of the stream
- memoryStream.Position = 0;
- byte[] encrypted = new byte[memoryStream.Length];
- memoryStream.Read(encrypted, 0, encrypted.Length);
- #endregion
- //Clean up.
- cs.Close();
- memoryStream.Close();
- return encrypted;
- }
- /// The other side: Decryption methods
- public string DecryptString(string EncryptedString)
- {
- return Decrypt(StrToByteArray(EncryptedString));
- }
- /// Decryption when working with byte arrays.
- public string Decrypt(byte[] EncryptedValue)
- {
- #region Write the encrypted value to the decryption stream
- MemoryStream encryptedStream = new MemoryStream();
- CryptoStream decryptStream = new CryptoStream(encryptedStream, DecryptorTransform, CryptoStreamMode.Write);
- decryptStream.Write(EncryptedValue, 0, EncryptedValue.Length);
- decryptStream.FlushFinalBlock();
- #endregion
- #region Read the decrypted value from the stream.
- encryptedStream.Position = 0;
- Byte[] decryptedBytes = new Byte[encryptedStream.Length];
- encryptedStream.Read(decryptedBytes, 0, decryptedBytes.Length);
- encryptedStream.Close();
- #endregion
- return UTFEncoder.GetString(decryptedBytes);
- }
- /// Convert a string to a byte array. NOTE: Normally we'd create a Byte Array from a string using an ASCII encoding (like so).
- // System.Text.ASCIIEncoding encoding = new System.Text.ASCIIEncoding();
- // return encoding.GetBytes(str);
- // However, this results in character values that cannot be passed in a URL. So, instead, I just
- // lay out all of the byte values in a long string of numbers (three per - must pad numbers less than 100).
- public byte[] StrToByteArray(string str)
- {
- if (str.Length == 0)
- throw new Exception("Invalid string value in StrToByteArray");
- byte val;
- byte[] byteArr = new byte[str.Length / 3];
- int i = 0;
- int j = 0;
- do
- {
- val = byte.Parse(str.Substring(i, 3));
- byteArr[j++] = val;
- i += 3;
- }
- while (i < str.Length);
- return byteArr;
- }
- // Same comment as above. Normally the conversion would use an ASCII encoding in the other direction:
- // System.Text.ASCIIEncoding enc = new System.Text.ASCIIEncoding();
- // return enc.GetString(byteArr);
- public string ByteArrToString(byte[] byteArr)
- {
- byte val;
- string tempStr = "";
- for (int i = 0; i <= byteArr.GetUpperBound(0); i++)
- {
- val = byteArr[i];
- if (val < (byte)10)
- tempStr += "00" + val.ToString();
- else if (val < (byte)100)
- tempStr += "0" + val.ToString();
- else
- tempStr += val.ToString();
- }
- return tempStr;
- }
- }
Add Comment
Please, Sign In to add comment