我的数据库中有一些使用单个密钥对称加密的数据。我没有将其硬编码到我的代码中,而是寻找一种更安全的方式来存储加密密钥。我可以在哪里安全地存放它?
在哪里存储服务器端加密密钥?
以下是您的可能性,大致按复杂程度降序排列。
使用外部硬件安全模块。有整个行业的产品旨在将安全敏感操作卸载到外部设备。这并没有解决问题,而是重新定位它,但它将它重新定位到更安全的设备上,所以总的来说它是一个安全的胜利。如果您正在做任何高风险的事情,那么这几乎肯定会成为您的解决方案的因素。
将加密绑定到您的硬件。理论上,HSM 正是这样做的,只是我们倾向于期望 HSM 比硬件支持的加密更复杂一点。但是,如果您不需要真正的 HSM 带来的吞吐量和合规性,则可以使用更便宜的选项。TPM 芯片的发明部分是为了这个目的,并且有很多例子展示了如何与它们集成。此外,专用的加密硬件已经变得相当便宜,并且为此重新使用诸如开源 U2F 密钥之类的设备比听起来简单。
将加密密钥绑定到您的管理员登录名(例如,使用您的管理员登录名加密加密密钥)。这只是略微有用,因为它需要您登录才能加密/解密任何内容。但从好的方面来说,除非您登录(即更大的控制权),否则没有人可以加密/解密任何东西。Windows 中的许多安全存储都是这样工作的。
启动时输入加密密钥,将其存储在内存中。这可以防止离线攻击(除非他们从 RAM 中捕获密钥,这更难做到)。类似于上面的选项,但也不同。但是,服务器启动到无法使用的状态,需要您手动提供密钥才能完成工作。
将密钥存储在不同的服务器上。例如,将密钥放在 Web 服务器上,将加密数据放在数据库服务器上。这在一定程度上保护了您,因为有人必须知道要获取密钥和数据库,而且他们还必须访问两台服务器。不是非常安全,但无论如何都是一个非常受欢迎的选择。大多数认为自己做得对的人都是这样做的。如果您正在考虑这样做,那么还要考虑上面提到的前两个选项之一。
将密钥存储在同一服务器上的其他位置。增加了边际安全性,但不是很多。大多数较小的操作都这样做——他们不应该这样做,但他们这样做了。通常是因为他们只有一台服务器,并且它在某处的某个云中运行。这就像把钥匙贴在门上而不是留在锁里一样;保证阻止最无能的攻击者。
将密钥存储在数据库中。现在你甚至没有尝试。尽管如此,一个令人沮丧的流行选择。
许多基于云的 KMS 解决方案(例如:AWS、GCP、Azure)在最有效地使用时会将您的加密绑定到您的云虚拟机或环境。虚拟机管理程序可以轻松建立和断言 VM 的唯一身份,并且 KMS 使用该身份和您分配给它的权限的组合来允许访问 HSM 管理的加密密钥。这类似于选项 1 和 2 的组合,经过调整以考虑云 VM 的短暂性。这些 KMS 解决方案通常还兼容平台的其他身份机制,有效地将加密密钥与登录密钥绑定;很像选项3。
我意识到这是不久前回答的,但举几个例子来说明泰勒的好回答:
我计划使用他的#3将密码绑定到服务帐户并使用 Powershell cmdlet 来获取它。这样脚本就不需要进行大量修改。服务帐户的密码位于 Active Directory 中,必须首先破解。这对我有用,因为我在两台服务器上使用过它。
对于他的#5,为了满足我们的合规性,我们能够将密钥以纯文本形式存储在另一台具有外部存储的服务器上,因为该存储本身已加密并且对其的访问受到限制。正如 Tyler 提到的,后者似乎并不那么安全,但即使对于一个强硬的评估者来说也足够好。
您可以为密钥管理创建两层架构。
- 加密表空间或基于列的静态数据的密钥。
- 解锁万能钥匙 1.
对于您的主密钥,请使用已建立的密钥管理解决方案之一,例如:
- 亚马逊 AWS KMS
- 甲骨文保险柜
- 微软 MKS。
- 或开源的。
请记住,您的密钥管理器必须支持与使用托管密钥的基础架构相同或更高的可用性。
将密钥分成两部分并将每个部分存储在 USB 闪存驱动器上怎么样?在系统启动时,USB 闪存驱动器将被插入到物理盒子中,组合并存储在应用程序上下文中。