【发布时间】:2020-05-06 07:30:22
【问题描述】:
我有一个应用程序,我正在检索磁盘中存在的对称加密密钥并使用它来加密数据。程序启动时从磁盘中检索加密密钥,并将其作为字节数组存储在私有类变量中。在程序启动时从磁盘检索密钥后,在密钥上使用ProtectedMemory.Protect() 来保护它。该密钥每次需要使用时都不受ProtectedMemory.Unprotect()的保护,使用后再次受到保护。
让我思考这个方案的有效性的部分是在从磁盘检索密钥的情况下,并且每次需要将密钥用作易于利用的漏洞时,都会在 2 个关键时刻创建程序的执行周期:当程序刚刚从磁盘加载完密钥并且没有调用Protect()方法时,以及密钥在加密期间没有被保护使用时。
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
}
}
提前致谢。
编辑:至于在磁盘上不关心密钥安全性的原因,密钥以相当安全的模糊形式存在于磁盘中,在检索时由StorageInt.FetchKey() 函数解密。
【问题讨论】:
-
你的链接中最薄弱的链条是什么?例如,密钥是否在磁盘上受到保护?
-
@LasseV.Karlsen 密钥在磁盘上时保持可靠安全。最薄弱的链条,我相信,一定是帖子中提到的两种场景。
-
.net 具有用于内存中安全密钥存储的特殊 clr 类型:SecureString (docs.microsoft.com/en-us/dotnet/api/…)。我会从 Windows 中的 x509 证书存储等安全存储中加载密钥 - 它看起来很安全。
标签: c# security cryptography encryption-symmetric dpapi