Stefan Prodan
Since MD5 and SHA1 are not consider secure any more, the hashing is done using SHA256 with a random salt. The salt can be hardcoded into your code or stored in a database. You can call the method with ref null as salt and the code will generate a random one using RNGCryptoServiceProvider. The string encryption / decryption methods uses Rijndael algorithm. Rijndael has been approved by NSA to be used for classified information protection.
Platform: .NET Framework 3.5
public static class ExtensionMethods2 { /// <summary> /// Suitable for password hashing /// </summary> /// <param name="salt">A random salt will be generated if input is null</param> /// <returns>Lenght 64</returns> public static string ComputeHash(this string str, ref string salt) { //if you don't care about the hash being reverted //SHA1Managed is faster with a smaller output var hasher = new SHA256Managed(); int keyLength = 4; byte[] data = Encoding.UTF8.GetBytes(str); byte[] key = new byte[keyLength]; byte[] dataReady = new byte[data.Length + keyLength]; if (salt == null) { //random salt using (var random = new RNGCryptoServiceProvider()) { random.GetNonZeroBytes(key); } salt = Convert.ToBase64String(key); } //memory consuming operation Array.Copy(Encoding.UTF8.GetBytes(salt), key, keyLength); Array.Copy(data, dataReady, data.Length); Array.Copy(key, 0, dataReady, data.Length, keyLength); //hash return BitConverter.ToString(hasher.ComputeHash(dataReady)).Replace("-", string.Empty); } /// <summary> /// Encrypt using Rijndael /// </summary> public static string Encrypt(this string str, string password) { byte[] salt = Encoding.UTF8.GetBytes(password.Length.ToString()); byte[] text = Encoding.UTF8.GetBytes(str); byte[] cipher; var key = new PasswordDeriveBytes(password, salt); using (ICryptoTransform encryptor = new RijndaelManaged().CreateEncryptor(key.GetBytes(32), key.GetBytes(16))) using (MemoryStream memoryStream = new MemoryStream()) using (CryptoStream cryptoStream = new CryptoStream(memoryStream, encryptor, CryptoStreamMode.Write)) { cryptoStream.Write(text, 0, text.Length); cryptoStream.FlushFinalBlock(); cipher = memoryStream.ToArray(); } return Convert.ToBase64String(cipher); } /// <summary> /// Decrypt Rijndael encrypted string /// </summary> public static string Decrypt(this string str, string password) { byte[] salt = Encoding.UTF8.GetBytes(password.Length.ToString()); byte[] text = Convert.FromBase64String(str); var key = new PasswordDeriveBytes(password, salt); int outLen; using (ICryptoTransform decryptor = new RijndaelManaged().CreateDecryptor(key.GetBytes(32), key.GetBytes(16))) using (MemoryStream memoryStream = new MemoryStream(text)) using (CryptoStream cryptoStream = new CryptoStream(memoryStream, decryptor, CryptoStreamMode.Read)) { text = new byte[text.Length]; outLen = cryptoStream.Read(text, 0, text.Length); } return Encoding.UTF8.GetString(text, 0, outLen); } }
http://www.stefanprodan.eu/2011/02/c-extensions-collection-no-2/