Fixed RNG generating null-bytes in metadata; causing read errors.

This commit is contained in:
h5p9sl 2018-12-19 02:33:31 -07:00
parent 7b5562c757
commit ca4ac3e5ce

View file

@ -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;