我在哪里安全地存储特定于应用程序的对称密钥?

信息安全 加密 视窗 密钥管理 AES 贮存
2021-09-06 13:15:24

我正在写一个应用程序App1此应用程序使用SQLite数据库,我计划使用AES256对其进行加密。对于对称加密,我需要一个密钥,我需要将它存储在某个地方。

类似的问题我有几个选择,但没有一个适用于我的情况:

  1. 将加密密钥绑定到您的管理员登录名

    我不信任当前登录的用户。事实上,我想对任何人隐藏这一点,但是App1

  2. 将加密密钥绑定到您的硬件。

    App1 部署到数千台机器上,有些可能不需要硬件。

  3. 启动时输入加密密钥,将其存储在内存中。

    用户不得访问App1密钥。

  4. 将密钥存储在不同的服务器上。

    机器在运行时允许离线App1

  5. 将密钥存储在同一服务器上的其他位置。

    然后就可以找到了。

  6. 将密钥存储在数据库中。

    我需要保护数据库,这在我的情况下是一种递归。

可能的解决方案是使用Windows DPAPI存储密钥,但是

  1. DPAPI 专注于为>用户<提供数据保护。

    而我需要保护应用程序。我还需要App1不同用户在同一台​​机器上工作

  2. 我可以添加辅助熵,以限制当前登录的用户访问数据。

    但是,我需要将这些秘密数据存储在机器上。我该如何保护...似乎又是递归了。

问题:我在哪里安全地存储应用程序特定的对称密钥?

4个回答

这是 DRM 的神奇问题,简而言之,没有好的答案,如果你想出一个,你会很富有。为了让应用程序访问密钥,它必须能够从未加密状态获取它,并且无论它可以做什么,足够高级的用户也可以做。

您可以使用 TPM(受信任的平台模块)或 HSM(硬件安全模块)来存储密钥,只要用户在系统上没有管理访问权限,但如果他们是管理员,那么他们很可能能够获得TPM 或 HSM 放弃密钥。也很难确保只有程序能够让 TPM 或 HSM 执行操作,因为应用程序无法向用户无法伪造的密钥存储验证自己,但它至少会保留钥匙本身是安全的。

如此简短的回答,如果用户在应用程序将运行的盒子上有管理员,那么你完全不走运。如果您只能给他们有限的帐户,那么有一些选择,但除非您将系统锁定相当多,否则它们仍然不是特别强大。

HSM 将是一个不错的选择。不幸的是,我不知道有任何 FOSS 实现。我偶尔会考虑做自己的“足够好/总比没有好”的 HSM。它不会经过 FIPS 认证或用环氧树脂封装并带有安全封条,但它比将钥匙放在盒子上要好。

HSM 的好处是您可以独立于请求/使用密钥的主机审核对密钥的访问。如果在没有机器重新启动或需要启动它的进程的时候检索到密钥,您将有理由进行调查并可能更改密钥。

由于您最有可能的解决方案是将密钥存储在服务器上的一个秘密位置,我建议使用 SELinux 来保护密钥不被除批准的用户/安全上下文之外的所有用户读取。

我还建议使用 auditd 在包含密钥的文件上放置特殊的审计规则,以便您可以随时跟踪文件被读取。强烈建议将审计日志从主机发送到日志收集主机。这为您提供了一些具有 HSM 的可审计性。

下面的呢?

1)创建一个公钥/私钥对。

2)用公钥加密你的对称密钥,并将其存储在代码中。

3)在启动时出示您的私钥以供程序读取(复制/粘贴到命令行)。

这样做的缺点是该过程是手动的,并且“所有者”必须是启动程序的人。

优点是它确实为您提供了安全性,因为私钥进入本地内存,如果编码正确,一旦用于解密就可以将其删除(在 java 中,使用 byte[] 然后将其清除)。

Windows 加密服务提供程序密钥库只能存储非对称密钥。为什么微软以这种方式设计它是一个非常好的问题。尽管如此,您唯一的解决方案是使用 HSM。您可以将应用程序密钥存储在您创建的数据存储中,并使用存储在 HSM 中的主密钥对其进行加密。

大多数现代 HSM 支持 API 调用的 PKCS#11 语法。HSM 可用作 PCI 卡和独立盒。
在选择 PCI 或独立选项之前,您还需要考虑您的整体加密需求。

您还将 HSM 管理员功能与服务器和数据库管理员分开。当您开始处理应用程序加密和敏感数据时,您实现了职责分离,这是基本的 InfoSec 原则。

请记住,加密是一种技术,任何人都可以通过调用 Crypto Service Provider API 进行加密。密码学是安全地生成密钥、安全地加密和解密数据、安全地存储密钥、防止未经授权的访问和轮换密钥的整个过程。随意应用加密会给您一种错误的安全感。