diff --git a/src/Encryptamajig/Encryptamajig.Tester/Encryptamajig.Tester.csproj b/src/Encryptamajig/Encryptamajig.Tester/Encryptamajig.Tester.csproj
index 33aac46..b9c3be4 100644
--- a/src/Encryptamajig/Encryptamajig.Tester/Encryptamajig.Tester.csproj
+++ b/src/Encryptamajig/Encryptamajig.Tester/Encryptamajig.Tester.csproj
@@ -35,6 +35,9 @@
prompt
4
+
+ Encryptamajig.Tester.Program
+
diff --git a/src/Encryptamajig/Encryptamajig.Tester/Program.cs b/src/Encryptamajig/Encryptamajig.Tester/Program.cs
index ad982c6..2a04008 100644
--- a/src/Encryptamajig/Encryptamajig.Tester/Program.cs
+++ b/src/Encryptamajig/Encryptamajig.Tester/Program.cs
@@ -19,9 +19,11 @@ static void Main(string[] args)
var encrypted = AesEncryptamajig.Encrypt(_plainText, _key);
var roundtrip = AesEncryptamajig.Decrypt(encrypted, _key);
- Debug.WriteLine(_plainText);
- Debug.WriteLine(encrypted);
- Debug.WriteLine(roundtrip);
+ Console.WriteLine(_plainText);
+ Console.WriteLine(encrypted);
+ Console.WriteLine(roundtrip);
+
+ Console.ReadLine();
}
}
}
diff --git a/src/Encryptamajig/Encryptamajig/AesEncryptamajig.cs b/src/Encryptamajig/Encryptamajig/AesEncryptamajig.cs
index f33de3d..b40c37e 100644
--- a/src/Encryptamajig/Encryptamajig/AesEncryptamajig.cs
+++ b/src/Encryptamajig/Encryptamajig/AesEncryptamajig.cs
@@ -5,6 +5,8 @@
using System.Linq;
using System.Security.Cryptography;
+
+
///
/// A simple wrapper to the AesManaged class and the AES algorithm.
/// Requires a securely stored key which should be a random string of characters that an attacker could never guess.
@@ -13,7 +15,13 @@
///
public class AesEncryptamajig
{
- private static readonly int _saltSize = 32;
+ // Preconfigured Encryption Parameters
+ public static readonly int BlockBitSize = 128; // To be sure we get the correct IV size, set the block size
+ public static readonly int KeyBitSize = 256; // AES 256 bit key encryption
+
+ // Preconfigured Password Key Derivation Parameters
+ public static readonly int SaltBitSize = 128;
+ public static readonly int Iterations = 10000;
///
/// Encrypts the plainText input using the given Key.
@@ -24,40 +32,53 @@ public class AesEncryptamajig
/// The salt and the ciphertext, Base64 encoded for convenience.
public static string Encrypt(string plainText, string key)
{
- if (string.IsNullOrEmpty(plainText))
- throw new ArgumentNullException("plainText");
+ //User Error Checks
if (string.IsNullOrEmpty(key))
throw new ArgumentNullException("key");
+ if (string.IsNullOrEmpty(plainText))
+ throw new ArgumentNullException("plainText");
- // Derive a new Salt and IV from the Key
- using (var keyDerivationFunction = new Rfc2898DeriveBytes(key, _saltSize))
- {
- var saltBytes = keyDerivationFunction.Salt;
- var keyBytes = keyDerivationFunction.GetBytes(32);
- var ivBytes = keyDerivationFunction.GetBytes(16);
-
- // Create an encryptor to perform the stream transform.
- // Create the streams used for encryption.
- using (var aesManaged = new AesManaged())
- using (var encryptor = aesManaged.CreateEncryptor(keyBytes, ivBytes))
- using (var memoryStream = new MemoryStream())
+ // Derive a new Salt and IV from the Key, using a 128 bit salt and 10,000 iterations
+ using (var keyDerivationFunction = new Rfc2898DeriveBytes(key, SaltBitSize / 8, Iterations))
+ using (var aesManaged = new AesManaged() { KeySize = KeyBitSize, BlockSize = BlockBitSize })
{
- using (var cryptoStream = new CryptoStream(memoryStream, encryptor, CryptoStreamMode.Write))
- using (var streamWriter = new StreamWriter(cryptoStream))
+ // Generate random IV
+ aesManaged.GenerateIV();
+
+ // Retrieve the Salt, Key and IV
+ byte[] saltBytes = keyDerivationFunction.Salt;
+ byte[] keyBytes = keyDerivationFunction.GetBytes(KeyBitSize / 8);
+ byte[] ivBytes = aesManaged.IV;
+
+ // Create an encryptor to perform the stream transform.
+ // Create the streams used for encryption.
+ using (var encryptor = aesManaged.CreateEncryptor(keyBytes, ivBytes))
+ using (var memoryStream = new MemoryStream())
{
- // Send the data through the StreamWriter, through the CryptoStream, to the underlying MemoryStream
- streamWriter.Write(plainText);
- }
- // Return the encrypted bytes from the memory stream, in Base64 form so we can send it right to a database (if we want).
- var cipherTextBytes = memoryStream.ToArray();
- Array.Resize(ref saltBytes, saltBytes.Length + cipherTextBytes.Length);
- Array.Copy(cipherTextBytes, 0, saltBytes, _saltSize, cipherTextBytes.Length);
+ using (var cryptoStream = new CryptoStream(memoryStream, encryptor, CryptoStreamMode.Write))
+ using (var streamWriter = new StreamWriter(cryptoStream))
+ {
+ // Send the data through the StreamWriter, through the CryptoStream, to the underlying MemoryStream
+ streamWriter.Write(plainText);
+ }
+
+ // Return the encrypted bytes from the memory stream in Base64 form.
+ var cipherTextBytes = memoryStream.ToArray();
- return Convert.ToBase64String(saltBytes);
+ // Resize saltBytes and append IV
+ Array.Resize(ref saltBytes, saltBytes.Length + ivBytes.Length);
+ Array.Copy(ivBytes, 0, saltBytes, SaltBitSize / 8, ivBytes.Length);
+
+ // Resize saltBytes with IV and append cipherText
+ Array.Resize(ref saltBytes, saltBytes.Length + cipherTextBytes.Length);
+ Array.Copy(cipherTextBytes, 0, saltBytes, (SaltBitSize / 8 ) + ivBytes.Length, cipherTextBytes.Length);
+
+ return Convert.ToBase64String(saltBytes);
+ }
}
}
- }
+
///
/// Decrypts the ciphertext using the Key.
@@ -71,22 +92,31 @@ public static string Decrypt(string ciphertext, string key)
throw new ArgumentNullException("cipherText");
if (string.IsNullOrEmpty(key))
throw new ArgumentNullException("key");
+
+ // Prepare the Salt and IV arrays
+ byte[] saltBytes = new byte[SaltBitSize / 8];
+ byte[] ivBytes = new byte[BlockBitSize / 8];
+
+ // Read all the bytes from the cipher text
+ byte[] allTheBytes = Convert.FromBase64String(ciphertext);
+
+ // Extract the Salt, IV from our ciphertext
+ Array.Copy(allTheBytes, 0, saltBytes, 0, saltBytes.Length);
+ Array.Copy(allTheBytes, saltBytes.Length, ivBytes, 0, ivBytes.Length);
- // Extract the salt from our ciphertext
- var allTheBytes = Convert.FromBase64String(ciphertext);
- var saltBytes = allTheBytes.Take(_saltSize).ToArray();
- var ciphertextBytes = allTheBytes.Skip(_saltSize).Take(allTheBytes.Length - _saltSize).ToArray();
+ // Extract the Ciphered bytes
+ byte[] ciphertextBytes = new byte[allTheBytes.Length - saltBytes.Length - ivBytes.Length];
+ Array.Copy(allTheBytes, saltBytes.Length + ivBytes.Length, ciphertextBytes, 0, ciphertextBytes.Length);
- using (var keyDerivationFunction = new Rfc2898DeriveBytes(key, saltBytes))
+ using (var keyDerivationFunction = new Rfc2898DeriveBytes(key, saltBytes,Iterations))
{
- // Derive the previous IV from the Key and Salt
- var keyBytes = keyDerivationFunction.GetBytes(32);
- var ivBytes = keyDerivationFunction.GetBytes(16);
-
+ // Get the Key bytes
+ var keyBytes = keyDerivationFunction.GetBytes(KeyBitSize / 8);
+
// Create a decrytor to perform the stream transform.
// Create the streams used for decryption.
// The default Cipher Mode is CBC and the Padding is PKCS7 which are both good
- using (var aesManaged = new AesManaged())
+ using (var aesManaged = new AesManaged() { KeySize = KeyBitSize, BlockSize = BlockBitSize })
using (var decryptor = aesManaged.CreateDecryptor(keyBytes, ivBytes))
using (var memoryStream = new MemoryStream(ciphertextBytes))
using (var cryptoStream = new CryptoStream(memoryStream, decryptor, CryptoStreamMode.Read))
@@ -97,5 +127,24 @@ public static string Decrypt(string ciphertext, string key)
}
}
}
+
+ ///
+ /// A simple method to hash a string using SHA512 hashing algorithm.
+ ///
+ /// The string to be hashed.
+ /// The hashed text.
+ public static string HashString(string inputString)
+ {
+ // Create the object used for hashing
+ using (var hasher = SHA512Managed.Create())
+ {
+ // Get the bytes of the input string and hash them
+ var inputBytes = System.Text.Encoding.UTF8.GetBytes(inputString);
+ var hashedBytes = hasher.ComputeHash(inputBytes);
+
+ return Convert.ToBase64String(hashedBytes);
+ }
+ }
+
}
}
\ No newline at end of file