使用 DPAPI 保护加密密钥:明显的漏洞?

Posted

技术标签:

【中文标题】使用 DPAPI 保护加密密钥:明显的漏洞?【英文标题】:Protecting encryption keys using DPAPI: Obvious hole? 【发布时间】:2010-03-05 14:26:39 【问题描述】:

我有一个基于 Windows.Forms 的 .NET 桌面应用程序,它将特权信息存储在磁盘上的文件中(不使用 .NET 配置文件),使用对称加密算法(例如使用 MS 的 CryptoAPI 的 TripleDES)进行加密。该文件必须在多个程序运行/机器电源循环中读取/写入,也就是每次都使用相同的密钥/IV。这里明显的问题是如何保护密钥(可能还有 IV),这里有几个关于 SO 的问题只是简单地说“使用 DPAPI”并给出一个往返加密/解密的简单示例。

我已经知道如何使用 DPAPI,但使用它来保护要馈送到另一个加密方案的密钥/IV 似乎存在一个明显的问题。考虑以下代码:

TripleDESCryptoServiceProvider^ cryptoprov = gcnew TripleDESCryptoServiceProvider;
cryptoprov->Key = ProtectedData::Unprotect(encryptedKey, salt, DataProtectionScope::CurrentUser);
cryptoprov->IV  = ProtectedData::Unprotect(encryptedIV,  salt, DataProtectionScope::CurrentUser);

由于你必须分配一个 SymmetricAlgorithm 派生类的 Key 和 IV,攻击者不能在这个点上设置一个断点,并且很容易找出 Key/IV 是什么吗?

我的问题如下:

我是否错过了使用 DPAPI 保护密钥的要点?你会怎么做? 我应该只使用 DPAPI 来加密我的文件吗?因此,不需要 Key/IV 存储。 我注意到存在用于非对称加密的 CspParameters。这本质上是比对称更好的选择吗? (在我的场景中,完全不对称与不对称)

谢谢!

【问题讨论】:

除非你有充分的理由,否则你应该使用 Rijndael,而不是 TripleDES。 【参考方案1】:

如果攻击者能够设置断点,你就已经输了。 攻击者只需在数据解密后设置断点读取明文即可。

你害怕什么样的攻击者?

如果你愿意,你可以写if (Debugger.IsAttached) Environment.FailFast(),但攻击者可以使用 Reflexil 删除检查。

【讨论】:

是的,好点子,如果他们能在解密后看到它,谁会愿意去寻找解密某些东西的密钥……我想我是在试图阻止想要找出敏感信息,但试图保护一个敬业的人似乎是在浪费时间。 攻击者是谁?系统管理员?有人在网络上吗?别人? 某人可以物理访问正在运行软件的机器,并且用户保持登录状态。假设合法用户已经离开并且没有锁定系统,并且一些 riff-raff 加强了它.他们拥有与运行我们软件的用户相同的凭据。 然后if (Debugger.IsAttached) Environment.FailFast(),在整个代码中散布,可能就足够了。【参考方案2】:

DPAPI 的目标是保护持久性数据不被窥探和篡改,它无法保护应用程序内存中的秘密数据。

【讨论】:

以上是关于使用 DPAPI 保护加密密钥:明显的漏洞?的主要内容,如果未能解决你的问题,请参考以下文章

DPAPI 密钥存储和恢复

代码缺陷解读:加密强度不足缺陷漏洞及使用过时方法缺陷

WPA2 Key Reinstallation 漏洞

.NET DPAPI 和 AES 加密:感知检查

在 Python 中使用 DPAPI?

CWE-780:RSA算法未使用最优非对称加密填充漏洞