I have an application where I am retrieving the symmetric encryption key present in the disk and using it to encrypt data. The encryption key is retrieved from the disk when the program starts and is stored as an array of bytes in a private class variable. Right after the key is retrieved from the disk on the start of the program, ProtectedMemory.Protect() is used on the key to protect it. The key is unprotected by ProtectedMemory.Unprotect() every time it needs to be used and is again protected after use.
The parts which has got me pondering on the effectiveness of this scheme is during the instances where the key is retrieved from the disk and every time the key needs to be used as an easily exploitable vulnerability is created during 2 key moments in the program's execution cycle: when the program has just finished loading the key from the disk and has not called the Protect() method and when the key is unprotected for use during encryption.
class ApplicationClass {
private byte[] encKey;
public ApplicationClass() {
// Fetches the encryption key first
encKey = StorageInt.FetchKey(); // Fetches and returns the encrypted key from the disk
// A gaping vulnerability here as the key is just loaded in memory and is not protected
ProtectedMemory.Protect(encKey, MemoryProtectionScope.SameProcess);
// Other initialization instructions follows
}
private byte[] ApplySymmEnc(byte[] plaintext) {
Aes aes = Aes.Create();
byte[] iv = new byte[128];
RNGCryptoServiceProvider randomBytesGenerator = new RNGCryptoServiceProvider();
randomBytesGenerator.GetNonZeroBytes(iv);
randomBytesGenerator.Dispose();
ProtectedMemory.Unprotect(encKey, MemoryProtectionScope.SameProcess);
// Another gaping vulnerability here!
ICryptoTransform encryptor = aes.CreateEncryptor(encKey, iv);
ProtectedMemory.Protect(encKey, MemoryProtectionScope.SameProcess); // Protect the key right after it is used for encryption
// Instructions for encryption follows
}
}
Thanks in advance.
EDIT: As for the reason on being unconcerned about the key's security while on the disk, the key exists in a reasonably secure obfuscated form in the disk which is deciphered by the StorageInt.FetchKey() function while retrieving.