Bug 242387. Security Audit: Use a random salt when generating encryption key from string. This prevents code book attacks.
This commit is contained in:
parent
f84d06fdd6
commit
a2ab8d3f36
46
CASA/micasad/cache/SecretStore.cs
vendored
46
CASA/micasad/cache/SecretStore.cs
vendored
@ -179,12 +179,14 @@ namespace sscs.cache
|
||||
byte[] baPasscode = CASACrypto.GetMasterPasscodeUsingDesktopPasswd(sDesktopPassword, GetPasscodeByDesktopFilePath(), false);
|
||||
if (CASACrypto.ValidatePasscode(baPasscode, GetValidationFilePath()))
|
||||
{
|
||||
ReEncryptPasscodeUsingRandomSalt(baPasscode, sDesktopPassword, GetPasscodeByDesktopFilePath());
|
||||
return true;
|
||||
}
|
||||
// try old salt
|
||||
baPasscode = CASACrypto.GetMasterPasscodeUsingDesktopPasswd(sDesktopPassword, GetPasscodeByDesktopFilePath(), true);
|
||||
if (CASACrypto.ValidatePasscode(baPasscode, GetValidationFilePath()))
|
||||
{
|
||||
ReEncryptPasscodeUsingRandomSalt(baPasscode, sDesktopPassword, GetPasscodeByDesktopFilePath());
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@ -338,6 +340,7 @@ namespace sscs.cache
|
||||
{
|
||||
lss = new LocalStorage(this, baPasscode);
|
||||
bIsStorePersistent = true;
|
||||
ReEncryptPasscodeUsingRandomSalt(baPasscode, desktopPasswd, GetPasscodeByDesktopFilePath());
|
||||
return true;
|
||||
}
|
||||
else
|
||||
@ -347,7 +350,8 @@ namespace sscs.cache
|
||||
if (CASACrypto.ValidatePasscode(baPasscode, GetValidationFilePath()))
|
||||
{
|
||||
// rewrite file using new encryption
|
||||
CASACrypto.EncryptAndStoreMasterPasscodeUsingString(baPasscode, desktopPasswd, GetPasscodeByDesktopFilePath());
|
||||
ReEncryptPasscodeUsingRandomSalt(baPasscode, desktopPasswd, GetPasscodeByDesktopFilePath());
|
||||
//CASACrypto.EncryptAndStoreMasterPasscodeUsingString(baPasscode, desktopPasswd, GetPasscodeByDesktopFilePath());
|
||||
lss = new LocalStorage(this, baPasscode);
|
||||
bIsStorePersistent = true;
|
||||
return true;
|
||||
@ -409,31 +413,29 @@ namespace sscs.cache
|
||||
baPasscode = CASACrypto.GetMasterPasscodeUsingDesktopPasswd(desktopPasswd, GetPasscodeByDesktopFilePath(), false);
|
||||
if (CASACrypto.ValidatePasscode(baPasscode, GetValidationFilePath()))
|
||||
{
|
||||
CASACrypto.EncryptAndStoreMasterPasscodeUsingString(
|
||||
baPasscode,
|
||||
mPasswd,
|
||||
GetPasscodeByMasterPasswdFilePath());
|
||||
CASACrypto.EncryptAndStoreMasterPasscodeUsingString(baPasscode, mPasswd, GetPasscodeByMasterPasswdFilePath());
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
// try old method
|
||||
baPasscode = CASACrypto.GetMasterPasscodeUsingDesktopPasswd(
|
||||
desktopPasswd,
|
||||
GetPasscodeByDesktopFilePath(),
|
||||
true);
|
||||
desktopPasswd,
|
||||
GetPasscodeByDesktopFilePath(),
|
||||
true);
|
||||
|
||||
if (CASACrypto.ValidatePasscode(baPasscode, GetValidationFilePath()))
|
||||
{
|
||||
// rewrite file using new method
|
||||
CASACrypto.EncryptAndStoreMasterPasscodeUsingString(
|
||||
baPasscode,
|
||||
desktopPasswd,
|
||||
GetPasscodeByDesktopFilePath());
|
||||
baPasscode,
|
||||
desktopPasswd,
|
||||
GetPasscodeByDesktopFilePath());
|
||||
|
||||
CASACrypto.EncryptAndStoreMasterPasscodeUsingString(
|
||||
baPasscode,
|
||||
mPasswd,
|
||||
GetPasscodeByMasterPasswdFilePath());
|
||||
baPasscode,
|
||||
mPasswd,
|
||||
GetPasscodeByMasterPasswdFilePath());
|
||||
return true;
|
||||
}
|
||||
else
|
||||
@ -518,6 +520,7 @@ namespace sscs.cache
|
||||
if (bIsStorePersistent == false)
|
||||
{
|
||||
lss = new LocalStorage(this, baPasscode);
|
||||
ReEncryptPasscodeUsingRandomSalt(baPasscode, mPasswd, GetPasscodeByMasterPasswdFilePath());
|
||||
bIsStorePersistent = true;
|
||||
}
|
||||
return true;
|
||||
@ -553,6 +556,7 @@ namespace sscs.cache
|
||||
if (bIsStorePersistent == false)
|
||||
{
|
||||
lss = new LocalStorage(this, baPasscode);
|
||||
ReEncryptPasscodeUsingRandomSalt(baPasscode, mPasswd, GetPasscodeByMasterPasswdFilePath());
|
||||
bIsStorePersistent = true;
|
||||
}
|
||||
return true;
|
||||
@ -566,6 +570,7 @@ namespace sscs.cache
|
||||
if (bIsStorePersistent == false)
|
||||
{
|
||||
lss = new LocalStorage(this, baPasscode);
|
||||
ReEncryptPasscodeUsingRandomSalt(baPasscode, mPasswd, GetPasscodeByMasterPasswdFilePath());
|
||||
bIsStorePersistent = true;
|
||||
}
|
||||
return true;
|
||||
@ -604,6 +609,7 @@ namespace sscs.cache
|
||||
byte[] baPasscode = CASACrypto.GetMasterPasscodeUsingDesktopPasswd(oldDesktopPasswd, GetPasscodeByDesktopFilePath(), false);
|
||||
if (CASACrypto.ValidatePasscode(baPasscode, GetValidationFilePath()))
|
||||
{
|
||||
ReEncryptPasscodeUsingRandomSalt(baPasscode, oldDesktopPasswd, GetPasscodeByDesktopFilePath());
|
||||
return baPasscode;
|
||||
}
|
||||
else
|
||||
@ -1071,7 +1077,7 @@ namespace sscs.cache
|
||||
// encrypt if an encryptionstring was passed
|
||||
if ((sEncryptionString != null) && (sEncryptionString.Length > 0))
|
||||
{
|
||||
byte[] baKey = sscs.crypto.CASACrypto.Generate16ByteKeyFromString(sEncryptionString, null, false);
|
||||
byte[] baKey = sscs.crypto.CASACrypto.Generate16ByteKeyFromString(sEncryptionString, null, false, false);
|
||||
|
||||
// now encypt it.
|
||||
baSecrets = sscs.crypto.CASACrypto.EncryptData(baSecrets, baKey, ref baIV);
|
||||
@ -1089,7 +1095,7 @@ namespace sscs.cache
|
||||
if (sEncryptionString != null)
|
||||
{
|
||||
// decrypt the buffer using the string passed in.
|
||||
byte[] baKey = sscs.crypto.CASACrypto.Generate16ByteKeyFromString(sEncryptionString, null, false);
|
||||
byte[] baKey = sscs.crypto.CASACrypto.Generate16ByteKeyFromString(sEncryptionString, null, false, false);
|
||||
byte[] baBuffer = sscs.crypto.CASACrypto.DecryptData(encryptedXmlSecrets, baKey, baIV);
|
||||
MergeXMLSecrets(baBuffer);
|
||||
}
|
||||
@ -1103,6 +1109,14 @@ namespace sscs.cache
|
||||
LocalStorage.AddXMLSecretsToStore(this, doc);
|
||||
}
|
||||
|
||||
private void ReEncryptPasscodeUsingRandomSalt(byte[] baPasscode, string sPassword, string sFilepath)
|
||||
{
|
||||
if (!File.Exists(sFilepath + ".salt"))
|
||||
{
|
||||
CASACrypto.EncryptAndStoreMasterPasscodeUsingString(baPasscode, sPassword, sFilepath);
|
||||
}
|
||||
}
|
||||
|
||||
internal void CreatePolicyDirectory()
|
||||
{
|
||||
|
||||
|
@ -40,12 +40,12 @@ namespace sscs.crypto
|
||||
private const int HASH_SIZE = 32;
|
||||
private const uint MAX_FILE_SIZE = 16 * 1024 * 1024; //16 MB
|
||||
|
||||
internal static byte[] Generate16ByteKeyFromString(string sTheString, string sFilepath, bool bUseOldMethod)
|
||||
internal static byte[] Generate16ByteKeyFromString(string sTheString, string sFilepath, bool bUseOldMethod, bool bGenerateRandomSalt)
|
||||
{
|
||||
byte[] baKey = new byte[16]; //return value
|
||||
try
|
||||
{
|
||||
Rfc2898DeriveBytes pkcs5 = new Rfc2898DeriveBytes(sTheString, SALTSIZE, ITERATION_COUNT, bUseOldMethod);
|
||||
Rfc2898DeriveBytes pkcs5 = new Rfc2898DeriveBytes(sTheString, SALTSIZE, ITERATION_COUNT, bUseOldMethod, sFilepath, bGenerateRandomSalt);
|
||||
baKey = pkcs5.GetBytes(16);
|
||||
}
|
||||
catch(Exception e)
|
||||
@ -531,7 +531,7 @@ namespace sscs.crypto
|
||||
{
|
||||
if(File.Exists(fileName))
|
||||
File.Delete(fileName);
|
||||
byte[] baKey = Generate16ByteKeyFromString(passwd, null, false);
|
||||
byte[] baKey = Generate16ByteKeyFromString(passwd, fileName, false, true);
|
||||
|
||||
//Get an encryptor.
|
||||
RijndaelManaged myRijndael = new RijndaelManaged();
|
||||
@ -578,7 +578,7 @@ namespace sscs.crypto
|
||||
|
||||
try
|
||||
{
|
||||
byte[] baKey = Generate16ByteKeyFromString(passwd, fileName, bTryOldMethod);
|
||||
byte[] baKey = Generate16ByteKeyFromString(passwd, fileName, bTryOldMethod, false);
|
||||
|
||||
/* Get a decryptor that uses the same key and
|
||||
* IV as the encryptor.
|
||||
|
@ -54,6 +54,7 @@
|
||||
//using System.Runtime.InteropServices;
|
||||
using System;
|
||||
using System.Text;
|
||||
using System.IO;
|
||||
using System.Security.Cryptography;
|
||||
|
||||
using sscs.lss;
|
||||
@ -105,11 +106,11 @@ namespace sscs.crypto {
|
||||
}
|
||||
|
||||
public Rfc2898DeriveBytes(string password, int saltSize, int iterations)
|
||||
: this (password, saltSize, iterations, false)
|
||||
: this (password, saltSize, iterations, false, null, false)
|
||||
{
|
||||
}
|
||||
|
||||
public Rfc2898DeriveBytes (string password, int saltSize, int iterations, bool bUseOldMethod)
|
||||
public Rfc2898DeriveBytes (string password, int saltSize, int iterations, bool bUseOldMethod, string sFilepath, bool bGenerateAndSaveRandomSalt)
|
||||
{
|
||||
if (password == null)
|
||||
throw new ArgumentNullException ("password");
|
||||
@ -122,13 +123,69 @@ namespace sscs.crypto {
|
||||
}
|
||||
else
|
||||
{
|
||||
Salt = GenerateNewSalt(password, saltSize);
|
||||
if (bGenerateAndSaveRandomSalt)
|
||||
{
|
||||
Salt = GenerateAndSaveRandomSalt(saltSize, sFilepath);
|
||||
}
|
||||
else
|
||||
{
|
||||
// load saved salt if one was saved
|
||||
if ((sFilepath != null) && (File.Exists(sFilepath + ".salt")))
|
||||
{
|
||||
Salt = LoadSavedSalt(sFilepath);
|
||||
}
|
||||
else
|
||||
{
|
||||
Salt = GenerateNewSalt(password, saltSize);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
IterationCount = iterations;
|
||||
_hmac = new HMACSHA1 (Encoding.UTF8.GetBytes (password));
|
||||
}
|
||||
|
||||
private byte[] GenerateAndSaveRandomSalt(int saltSize, string sFilepath)
|
||||
{
|
||||
byte[] randomSalt = new byte[saltSize];
|
||||
FastRandom fr = new FastRandom();
|
||||
fr.NextBytes(randomSalt);
|
||||
|
||||
// save salt
|
||||
try
|
||||
{
|
||||
FileStream fs = new FileStream(sFilepath + ".salt", FileMode.Create);
|
||||
fs.Write(randomSalt, 0, randomSalt.Length);
|
||||
fs.Flush();
|
||||
fs.Close();
|
||||
File.SetAttributes(sFilepath + ".salt", FileAttributes.Hidden);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
return randomSalt;
|
||||
}
|
||||
|
||||
private byte[] LoadSavedSalt(string sFilePath)
|
||||
{
|
||||
byte[] baSalt = null;
|
||||
|
||||
try
|
||||
{
|
||||
FileStream fs = new FileStream(sFilePath + ".salt", FileMode.Open);
|
||||
baSalt = new byte[fs.Length];
|
||||
fs.Read(baSalt, 0, (int)fs.Length);
|
||||
fs.Close();
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
|
||||
}
|
||||
return baSalt;
|
||||
}
|
||||
|
||||
private static byte[] GenerateOldSalt(string password, int saltSize)
|
||||
{
|
||||
byte[] buffer = new byte[saltSize];
|
||||
|
Loading…
Reference in New Issue
Block a user