Security Audit 4.1. Enhanced Persistence encryption salt generation
to be more random based on the password or master password used.
This commit is contained in:
@@ -39,19 +39,19 @@ namespace sscs.crypto
|
||||
private const int ITERATION_COUNT = 1000;
|
||||
private const int HASH_SIZE = 32;
|
||||
|
||||
internal static byte[] Generate16ByteKeyFromString(string sTheString)
|
||||
internal static byte[] Generate16ByteKeyFromString(string sTheString, string sFilepath, bool bUseOldMethod)
|
||||
{
|
||||
byte[] baKey = new byte[16]; //return value
|
||||
try
|
||||
{
|
||||
Rfc2898DeriveBytes pkcs5 = new Rfc2898DeriveBytes(sTheString, SALTSIZE, ITERATION_COUNT);
|
||||
Rfc2898DeriveBytes pkcs5 = new Rfc2898DeriveBytes(sTheString, SALTSIZE, ITERATION_COUNT, bUseOldMethod);
|
||||
baKey = pkcs5.GetBytes(16);
|
||||
}
|
||||
catch(Exception e)
|
||||
{
|
||||
{
|
||||
CSSSLogger.ExpLog(e.ToString());
|
||||
CSSSLogger.DbgLog("Key generation failed");
|
||||
baKey = null;
|
||||
baKey = null;
|
||||
}
|
||||
return baKey;
|
||||
}
|
||||
@@ -68,7 +68,7 @@ namespace sscs.crypto
|
||||
//Get an encryptor.
|
||||
RijndaelManaged myRijndael = new RijndaelManaged();
|
||||
ICryptoTransform encryptor;
|
||||
encryptor = myRijndael.CreateEncryptor(baMasterPasscode, baMasterPasscode);
|
||||
encryptor = myRijndael.CreateEncryptor(baMasterPasscode, GenerateAndSaveIV(fileName, myRijndael));
|
||||
|
||||
//Encrypt the data to a file
|
||||
fsEncrypt = new FileStream(fileName, FileMode.Create);
|
||||
@@ -126,7 +126,7 @@ namespace sscs.crypto
|
||||
*/
|
||||
|
||||
RijndaelManaged myRijndael = new RijndaelManaged();
|
||||
ICryptoTransform decryptor = myRijndael.CreateDecryptor(baMasterPasscode, baMasterPasscode);
|
||||
ICryptoTransform decryptor = myRijndael.CreateDecryptor(baMasterPasscode, RetrieveIV(fileName, baMasterPasscode));
|
||||
//Now decrypt
|
||||
fsDecrypt = new FileStream(fileName, FileMode.Open);
|
||||
|
||||
@@ -176,14 +176,10 @@ namespace sscs.crypto
|
||||
FileStream fsEncrypt = null;
|
||||
CryptoStream csEncrypt = null;
|
||||
try
|
||||
{
|
||||
byte[] IV = new byte[16];
|
||||
for(int z = 0 ; z < 16; z++ )
|
||||
IV[z] = key[z];
|
||||
|
||||
{
|
||||
//Get an encryptor.
|
||||
RijndaelManaged myRijndael = new RijndaelManaged();
|
||||
ICryptoTransform encryptor = myRijndael.CreateEncryptor(key, IV);
|
||||
ICryptoTransform encryptor = myRijndael.CreateEncryptor(key, GenerateAndSaveIV(fileName, myRijndael));
|
||||
|
||||
//Encrypt the data to a file
|
||||
fsEncrypt = new FileStream(fileName, FileMode.Create);
|
||||
@@ -196,13 +192,24 @@ namespace sscs.crypto
|
||||
byte[] hash = sha.ComputeHash(xmlData);
|
||||
|
||||
fsEncrypt.Write(hash,0,hash.Length);
|
||||
fsEncrypt.Flush();
|
||||
|
||||
fsEncrypt.Flush();
|
||||
|
||||
#if CLEAR
|
||||
byte[] dup = (byte[])xmlData.Clone();
|
||||
// write clear file
|
||||
FileStream fsClear = new FileStream(fileName + ".xml", FileMode.Create);
|
||||
fsClear.Write(dup, 0, dup.Length);
|
||||
fsClear.Flush();
|
||||
fsClear.Close();
|
||||
#endif
|
||||
|
||||
|
||||
csEncrypt = new CryptoStream(fsEncrypt, encryptor, CryptoStreamMode.Write);
|
||||
|
||||
//Write all data to the crypto stream and flush it.
|
||||
csEncrypt.Write(xmlData, 0, xmlData.Length);
|
||||
csEncrypt.FlushFinalBlock();
|
||||
|
||||
}
|
||||
catch(Exception e)
|
||||
{
|
||||
@@ -228,7 +235,7 @@ namespace sscs.crypto
|
||||
|
||||
//Get a decryptor that uses the same key and IV as the encryptor.
|
||||
RijndaelManaged myRijndael = new RijndaelManaged();
|
||||
ICryptoTransform decryptor = myRijndael.CreateDecryptor(key, IV);
|
||||
ICryptoTransform decryptor = myRijndael.CreateDecryptor(key, RetrieveIV(fileName, key));
|
||||
#if LINUX
|
||||
UnixFileInfo fsTest = new UnixFileInfo (fileName);
|
||||
if((fsTest == null) || !(fsTest.Exists) || fsTest.IsSymbolicLink)
|
||||
@@ -248,8 +255,8 @@ namespace sscs.crypto
|
||||
if(fsDecrypt.Length < HASH_SIZE )
|
||||
{
|
||||
csDecrypt.Close();
|
||||
fsDecrypt.Close();
|
||||
return null;
|
||||
fsDecrypt.Close();
|
||||
return null;
|
||||
}
|
||||
|
||||
ulong fileLen = (ulong)(fsDecrypt.Length - HASH_SIZE);
|
||||
@@ -273,15 +280,25 @@ namespace sscs.crypto
|
||||
fsDecrypt.Close();
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
csDecrypt.Close();
|
||||
}
|
||||
catch { }
|
||||
|
||||
try
|
||||
{
|
||||
fsDecrypt.Close();
|
||||
}
|
||||
catch { }
|
||||
|
||||
csDecrypt.Close();
|
||||
fsDecrypt.Close();
|
||||
return tmpEncrypt;
|
||||
}
|
||||
catch(Exception e)
|
||||
{
|
||||
Console.WriteLine(e.ToString());
|
||||
{
|
||||
CSSSLogger.DbgLog(e.ToString());
|
||||
}
|
||||
if (csDecrypt != null)
|
||||
{
|
||||
@@ -301,6 +318,7 @@ namespace sscs.crypto
|
||||
/* Encrypts the data with the key and returns the encrypted buffer.
|
||||
*/
|
||||
|
||||
/*
|
||||
internal static byte[] EncryptData(byte[] data, byte[] key)
|
||||
{
|
||||
|
||||
@@ -329,10 +347,11 @@ namespace sscs.crypto
|
||||
return null;
|
||||
}
|
||||
|
||||
*/
|
||||
/* Decrypts the buffer(encrypted) with the key and returns the
|
||||
* decrypted data.
|
||||
*/
|
||||
|
||||
/*
|
||||
internal static byte[] DecryptData(byte[] buffer, byte[] key)
|
||||
{
|
||||
try
|
||||
@@ -356,7 +375,7 @@ namespace sscs.crypto
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
*/
|
||||
/* This method checks if we can get the master passcode by
|
||||
* decrypting the passwds file ( where we store all possible
|
||||
* passwds cross-encrypted.
|
||||
@@ -373,7 +392,7 @@ namespace sscs.crypto
|
||||
|
||||
internal static byte[] GetMasterPasscode(string desktopPasswd, string fileName)
|
||||
{
|
||||
byte[] mp = DecryptMasterPasscodeUsingString(desktopPasswd, fileName);
|
||||
byte[] mp = DecryptMasterPasscodeUsingString(desktopPasswd, fileName, false);
|
||||
return mp;
|
||||
}
|
||||
|
||||
@@ -394,7 +413,7 @@ namespace sscs.crypto
|
||||
{
|
||||
if(File.Exists(fileName))
|
||||
File.Delete(fileName);
|
||||
byte[] baKey = Generate16ByteKeyFromString(passwd);
|
||||
byte[] baKey = Generate16ByteKeyFromString(passwd, null, false);
|
||||
|
||||
|
||||
//Get an encryptor.
|
||||
@@ -434,61 +453,68 @@ namespace sscs.crypto
|
||||
}
|
||||
|
||||
public static byte[] DecryptMasterPasscodeUsingString(string passwd,
|
||||
string fileName)
|
||||
string fileName, bool bTryOldMethod)
|
||||
{
|
||||
FileStream fsDecrypt = null;
|
||||
CryptoStream csDecrypt = null;
|
||||
byte[] baSavedMasterPasscode = null;
|
||||
try
|
||||
{
|
||||
byte[] baKey = Generate16ByteKeyFromString(passwd);
|
||||
|
||||
/* Get a decryptor that uses the same key and
|
||||
* IV as the encryptor.
|
||||
*/
|
||||
RijndaelManaged myRijndael = new RijndaelManaged();
|
||||
ICryptoTransform decryptor = myRijndael.CreateDecryptor(baKey,
|
||||
baKey);
|
||||
//Now decrypt
|
||||
byte[] baSavedMasterPasscode = null;
|
||||
|
||||
try
|
||||
{
|
||||
byte[] baKey = Generate16ByteKeyFromString(passwd, fileName, bTryOldMethod);
|
||||
|
||||
/* Get a decryptor that uses the same key and
|
||||
* IV as the encryptor.
|
||||
*/
|
||||
RijndaelManaged myRijndael = new RijndaelManaged();
|
||||
ICryptoTransform decryptor = myRijndael.CreateDecryptor(baKey, RetrieveIV(fileName, baKey));
|
||||
//Now decrypt
|
||||
#if LINUX
|
||||
UnixFileInfo fsTest = new UnixFileInfo (fileName);
|
||||
if((fsTest == null) || !(fsTest.Exists) || fsTest.IsSymbolicLink)
|
||||
#else
|
||||
if(!File.Exists(fileName))
|
||||
#endif
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
fsDecrypt = new FileStream(fileName, FileMode.Open);
|
||||
csDecrypt = new CryptoStream(fsDecrypt, decryptor,
|
||||
CryptoStreamMode.Read);
|
||||
baSavedMasterPasscode = new byte[16];
|
||||
|
||||
//Read the data out of the crypto stream.
|
||||
csDecrypt.Read(baSavedMasterPasscode, 0, 16);
|
||||
}
|
||||
catch(Exception e)
|
||||
{
|
||||
CSSSLogger.ExpLog(e.ToString());
|
||||
CSSSLogger.DbgLog("Unable to decrypt master passode");
|
||||
baSavedMasterPasscode = null;
|
||||
}
|
||||
|
||||
#else
|
||||
if (!File.Exists(fileName))
|
||||
#endif
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
fsDecrypt = new FileStream(fileName, FileMode.Open);
|
||||
csDecrypt = new CryptoStream(fsDecrypt, decryptor,
|
||||
CryptoStreamMode.Read);
|
||||
baSavedMasterPasscode = new byte[16];
|
||||
|
||||
//Read the data out of the crypto stream.
|
||||
csDecrypt.Read(baSavedMasterPasscode, 0, 16);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
CSSSLogger.ExpLog(e.ToString());
|
||||
CSSSLogger.DbgLog("Unable to decrypt master passode");
|
||||
baSavedMasterPasscode = null;
|
||||
}
|
||||
|
||||
|
||||
try
|
||||
{
|
||||
if (csDecrypt != null)
|
||||
csDecrypt.Close();
|
||||
}
|
||||
catch { }
|
||||
|
||||
|
||||
if (fsDecrypt != null)
|
||||
fsDecrypt.Close();
|
||||
|
||||
|
||||
if (csDecrypt != null)
|
||||
csDecrypt.Close();
|
||||
|
||||
if ( fsDecrypt != null )
|
||||
fsDecrypt.Close();
|
||||
|
||||
|
||||
return baSavedMasterPasscode;
|
||||
}
|
||||
|
||||
internal static byte[] GetMasterPasscodeUsingMasterPasswd(
|
||||
string mPasswd,
|
||||
string fileName)
|
||||
string fileName,
|
||||
bool bUseOldMethod)
|
||||
{
|
||||
byte[] baMasterPasscode;
|
||||
try
|
||||
@@ -498,8 +524,7 @@ namespace sscs.crypto
|
||||
/* Decrypt the passcode from the file using master passwd.
|
||||
* and return the decrypted passcode.
|
||||
*/
|
||||
baMasterPasscode = DecryptMasterPasscodeUsingString(mPasswd,
|
||||
fileName);
|
||||
baMasterPasscode = DecryptMasterPasscodeUsingString(mPasswd, fileName, bUseOldMethod);
|
||||
return baMasterPasscode;
|
||||
}
|
||||
else
|
||||
@@ -515,7 +540,8 @@ namespace sscs.crypto
|
||||
|
||||
internal static byte[] GetMasterPasscodeUsingDesktopPasswd(
|
||||
string desktopPasswd,
|
||||
string fileName)
|
||||
string fileName,
|
||||
bool bUseOldMethod)
|
||||
{
|
||||
byte[] passcode;
|
||||
try
|
||||
@@ -526,7 +552,7 @@ namespace sscs.crypto
|
||||
* and return the decrypted passcode.
|
||||
*/
|
||||
passcode = DecryptMasterPasscodeUsingString(desktopPasswd,
|
||||
fileName);
|
||||
fileName, bUseOldMethod);
|
||||
return passcode;
|
||||
|
||||
}
|
||||
@@ -581,7 +607,9 @@ namespace sscs.crypto
|
||||
/* Here we decrpyt a well known string, throw exception
|
||||
* if not successful
|
||||
* A well-known string is encrpyted by the Passcode and saved
|
||||
*/
|
||||
*/
|
||||
|
||||
CSSSLogger.DbgLog("Validate called");
|
||||
|
||||
if ((baPasscode == null) || baPasscode.Length < 1 )
|
||||
return false;
|
||||
@@ -593,11 +621,13 @@ namespace sscs.crypto
|
||||
char[] trimChars = {'\0'};
|
||||
sString = sString.TrimEnd(trimChars);
|
||||
if( ConstStrings.MICASA_VALIDATION_STRING.Equals(sString))
|
||||
{
|
||||
{
|
||||
CSSSLogger.DbgLog("Passed");
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
{
|
||||
CSSSLogger.DbgLog("Failed");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -607,7 +637,49 @@ namespace sscs.crypto
|
||||
CSSSLogger.DbgLog("Validation of passcode failed.");
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
private static byte[] GenerateAndSaveIV(string sFileName, RijndaelManaged theRiManaged)
|
||||
{
|
||||
theRiManaged.GenerateIV();
|
||||
byte[] baIV = theRiManaged.IV;
|
||||
|
||||
try
|
||||
{
|
||||
// now save this
|
||||
FileStream fs = new FileStream(sFileName + ".IV", FileMode.Create);
|
||||
fs.Write(baIV, 0, 16);
|
||||
fs.Flush();
|
||||
fs.Close();
|
||||
|
||||
File.SetAttributes(sFileName + ".IV", FileAttributes.Hidden);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
CSSSLogger.DbgLog(e.ToString());
|
||||
}
|
||||
|
||||
return baIV;
|
||||
}
|
||||
|
||||
private static byte[] RetrieveIV(string sFileName, byte[] baOrigValue)
|
||||
{
|
||||
|
||||
byte[] IV = new byte[16];
|
||||
// check for file existence
|
||||
try
|
||||
{
|
||||
FileStream fs = new FileStream(sFileName + ".IV", FileMode.Open);
|
||||
fs.Read(IV, 0, 16);
|
||||
fs.Close();
|
||||
return IV;
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
CSSSLogger.DbgLog(e.ToString());
|
||||
}
|
||||
return (byte[])baOrigValue.Clone();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user