diff --git a/Crypto Notepad/AES.cs b/Crypto Notepad/AES.cs index 37b919e..0d1fc27 100644 --- a/Crypto Notepad/AES.cs +++ b/Crypto Notepad/AES.cs @@ -83,12 +83,43 @@ public bool GetMetadata(byte[] rawData) class AES { + private static bool ByteArrayIsNonZero(byte[] byte_array) + { + foreach (byte i in byte_array) + { + if (i == 0) + { + return false; + } + } + return true; + } + + // The purpose of this function is to ensure that the bytes generated by it are nonzero 100% of the time + // as there was a strange bug in which RNGCryptoServiceProvider.GetNonZeroBytes() would return a null byte sometimes + private static byte[] GenerateSecureNonZeroByteArray(int length) + { + byte[] result = new byte[length]; + + using (RNGCryptoServiceProvider rng = new RNGCryptoServiceProvider()) + { + do + { + rng.GetNonZeroBytes(result); + } while (!ByteArrayIsNonZero(result)); + } + + return result; + } + public static string Encrypt(string plainText, string password, string salt = null, string hashAlgorithm = "SHA1", int passwordIterations = 2, int keySize = 256) { if (string.IsNullOrEmpty(plainText)) - return ""; + return null; + if (string.IsNullOrEmpty(password)) + return null; byte[] plainTextBytes; byte[] saltValueBytes; @@ -97,9 +128,7 @@ public static string Encrypt(string plainText, string password, if (string.IsNullOrEmpty(salt)) { saltValueBytes = new byte[64]; // Nice and long - RandomNumberGenerator rng = RandomNumberGenerator.Create(); - rng.GetNonZeroBytes(saltValueBytes); - rng.Dispose(); + saltValueBytes = GenerateSecureNonZeroByteArray(saltValueBytes.Length); } else { @@ -117,7 +146,9 @@ public static string Encrypt(string plainText, string password, byte[] keyBytes = derivedPassword.GetBytes(keySize / 8); RijndaelManaged symmetricKey = new RijndaelManaged(); symmetricKey.Mode = CipherMode.CBC; - symmetricKey.GenerateIV(); + + // Generate IV + symmetricKey.IV = GenerateSecureNonZeroByteArray(symmetricKey.IV.Length); byte[] cipherTextBytes = null; @@ -151,6 +182,8 @@ public static string Decrypt(string cipherText, string password, string salt = " { if (string.IsNullOrEmpty(cipherText)) return null; + if (string.IsNullOrEmpty(password)) + return null; byte[] initialVectorBytes; byte[] saltValueBytes;