我有一个应用程序,在其中检索磁盘中存在的对称加密密钥,并使用它来加密数据。程序启动时从磁盘检索加密密钥,并将其作为字节数组存储在私有类变量中。在程序启动时从磁盘中检索到密钥之后,立即在密钥上使用ProtectedMemory.Protect()
对其进行保护。每次需要使用ProtectedMemory.Unprotect()
时,密钥均不受保护,使用后再次受到保护。
使我思考该方案有效性的部分是在从磁盘中检索密钥的情况下,并且每次需要在程序的两个关键时刻创建密钥以用作易于利用的漏洞时,执行周期:当程序刚从磁盘完成密钥加载并且尚未调用Protect()
方法,并且密钥在加密过程中未受保护时使用。
class ApplicationClass {
private byte[] encKey;
public ApplicationClass() {
// Fetches the encryption key fir.st
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
}
}
提前感谢。
防范all攻击是不可能的。您可以获得的最接近的大概是使用Trusted Platform Module(tpm)芯片,因此密钥永远不会离开芯片。第二好的可能是使用trusted execution environment(如果您的处理器提供了此功能)。但是,它们都不是不受各种攻击影响的。
如果没有专用的硬件支持,尝试保护程序不受管理员的攻击可能是不可行的。如果攻击者可以读取程序的内存,为什么他不能仅从磁盘读取密钥?
加密ram中的密钥对于防止诸如冷启动攻击之类的攻击非常有用,并且可能很难及时在脆弱的时刻正确获取密钥。
问题best practices for keys in memory中也有一些可能有用的答案。