我的数据库中有一些用单个密钥对称加密的数据。我正在寻找一种更安全的方式来存储加密密钥,而不是将其硬编码到我的代码中。我可以在哪里安全存放它?

评论

确实没有办法存储它,至少不能以安全的方式存储它,需要更多信息来扩展此注释。

没有安全的硬件,我想您很不幸。这就是为什么最常见的是存储密码的哈希值而不是密码的加密版本。如果您拥有TPM之类的安全硬件,则可以使用。

对于正在为运行在Amazon Web Services中的应用程序寻找密钥管理解决方案的人来说,AWS密钥管理服务(KMS)可能是一个不错的选择。

#1 楼

这是您的可能,大致以递减的顺序。


使用外部硬件安全模块。整个产品行业旨在将对安全敏感的操作卸载到外部设备。这并不能解决问题,只需重新安置它,而是将其重新安置到安全性更高的设备上,因此总的来说是安全的胜利。如果您正在做任何高风险的事情,那么几乎可以肯定这将成为您解决方案的一部分。
将加密与硬件联系起来。从理论上讲,HSM正是这样做的,只有我们倾向于期望HSM不仅仅是硬件支持的加密技术。但是,如果您不需要真正的HSM带来的吞吐量和合规性,则可以使用更便宜的选择。 TPM芯片是为此目的而部分发明的,并且存在许多示例,展示了如何与它们集成。此外,专用的加密硬件已经变得相当便宜,为此,重新使用诸如“开源U2F密钥”之类的设备要比听起来简单。
将加密密钥绑定到您的管理员登录名(例如,使用您的管理员登录名对加密密钥进行加密)。这仅勉强有用,因为它要求您登录才能加密/解密任何内容。但从好的方面说,除非您登录(没有更好的控制权),否则没有人可以加密/解密任何东西。 Windows中的许多安全存储都是这样的。
启动时键入加密密钥,然后将其存储在内存中。这样可以防止离线攻击(除非它们将密钥从RAM中捕获,这很难做到)。与以上选项相似,但也有所不同。但是,服务器会引导到无法使用的状态,需要您手动提供密钥才能完成工作。
将密钥存储在其他服务器上。例如。将密钥放在Web服务器上,并将加密的数据放在数据库服务器上。这在某种程度上为您提供了保护,因为有人必须知道要获取密钥以及数据库,而且他们还必须有权访问这两个服务器。并不是很安全,但是无论如何都是一个非常受欢迎的选择。大多数认为自己做对的人都是这样做的。如果您正在考虑这样做,那么请考虑上面提到的前两个选项之一。
将密钥存储在同一服务器上的其他位置。增加了边际安全性,但不是很多。大多数较小的操作都这样做-不应该,但是可以。通常是因为它们只有一台服务器,并且在某些地方的云中运行。这就像在敲门钥匙而不是将其留在锁中一样。保证阻止最无能的攻击者。
将密钥存储在数据库中。现在,您甚至都没有尝试。仍然是令人沮丧的流行选择。

许多基于云的KMS解决方案(例如AWS,GCP,Azure)最有效地使用时,会将您的加密绑定到您的云VM或环境。虚拟机管理程序很容易建立和声明VM的唯一标识,并且KMS使用该标识和您为其分配的权限的组合来允许访问由HSM管理的加密密钥。这类似于选项1和2的组合,这些选项经过调制以说明Cloud VM的短暂性。这些KMS解决方案通常还与平台的其他标识机制兼容,从而有效地将加密密钥与登录密钥绑定在一起。非常像选项3。

评论


我正在处理相同的问题,我试图在静止时使用加密,并且我需要将加密密钥放在文件系统上。如果它是只能读取一次并在启动时远程提供的临时文件,则可能没问题。这样做的目的是防止文件系统的tar足以恢复数据库。我前不久在vault.io中研究了这种情况,但是当连接到秘密服务器需要...磁盘上的私钥(x509验证)时,它只是解决了问题。

–Rob
16年1月28日在15:55

将密钥放在外部服务中(选择1 + 5)后,您便具有在服务器上以纯文本格式访问这些服务的凭据。因此问题没有解决,您刚刚创建了新一类问题。如何避免这些?

–克里斯·塞弗特(Chris Seufert)
18年5月8日在3:48

@ChrisSeufert我同意这适用于选项1,但并不完全适用于选项5,在这里,如果有人捕获了数据库,则他们不能在不访问进行加密的服务器的情况下解密数据。该数据库未指向其他服务器。

–伊恩·沃伯顿(Ian Warburton)
19-10-11在16:08



@IanWarburton假定谁设法捕获数据库,首先都不是从Web服务器执行的。但是是的,我可以看到选项5比在一台机器上的所有选项更安全。

–克里斯·塞弗特(Chris Seufert)
19-10-14在3:25

我真的不认为他们中的任何一个真正能解决问题,它们只是混淆如何获取密钥并暂时减慢攻击者的不同方式。考虑#1选项,假设您有一些服务/应用服务器可以向HSM请求签名/加密/解密内容,那么进入该服务器与拥有HSM私钥基本上相同,因为您可以发送数据到HSM,并对其进行签名/加密/解密。

– hPNJ7MHTyg
20 May 27'1:59

#2 楼

我知道这是在不久前回答的,但是举两个例子说明泰勒的好答案:


我计划使用他的#3将密码绑定到服务帐户并使用一个Powershell cmdlet来抓取它。这样,脚本就不需要进行大量修改。服务帐户的密码在Active Directory中,必须首先被泄露。这对我有用,因为我已经在两台服务器上使用过它。
对于他的#5,为了满足我们的要求,我们能够将纯文本密钥存储在具有外部存储的另一台服务器上,因为该存储本身是加密的并且对其访问受到限制。正如泰勒(Tyler)提到的那样,后者似乎并不安全,但即使对于一个严谨的评估者来说也足够好。

#3 楼

您可以创建用于密钥管理的两层体系结构。


用于静态加密数据的密钥对表空间进行加密,或者基于列的密钥。为主密钥解锁1.

使用已建立的密钥管理解决方案之一,例如:


Amazon AWS KMS
Oracle Vault
Microsoft MKS。
或开放源代码。

请记住,与使用托管密钥的基础架构相比,密钥管理器必须支持相同或更高的可用性。 。

评论


这对于集中式密钥管理非常有用。但这如何支持安全性?从现在开始,您需要存储您的asw kms凭证,以便能够达到aws kms。我很困惑。我不是唯一的一个。

–musicformellons
18年5月16日在11:13

#4 楼

将密钥分为两部分并将每个部分存储在USB闪存驱动器上怎么办?在系统启动时,会将USB闪存驱动器插入物理盒中,进行组合,然后存储在应用程序上下文中。