私钥存储在哪里?


22

假设我希望对软件的某些部分进行加密。例如,数据库的凭据等。我需要将这些值存储在某个位置,但是以明文形式存储将使攻击者更容易获得未经授权的访问。

但是,如果我加密了一些明文,那么该密钥存储在哪里?该软件可以访问的任何内容,无论混淆的级别如何,坚定的攻击者都可以访问:

  • 假设密钥受文件系统的安全模型保护;但是(恶意)超级用户或不提供这种保真度的平台又如何呢?
  • 或将密钥硬编码到软件二进制文件中,但始终可以将其反编译,那么开源软件或解释代码又如何呢?
  • 如果生成了密钥,则此类算法将需要确定性(大概),然后将相同的问题应用于种子。
  • 等等

密码学只有其链中最薄弱的一环才有力,这似乎是一个松散的环节!假设这是完成工作的正确工具(请嘲笑我),那么如何才能可靠地保护此类信息呢?


关于适合该工作的工具:例如,在服务访问(数据库,身份验证服务器等)的情况下,您可能会使用服务帐户(可能是某些服务级别)限制对该层的访问审核等),因此不必担心使用明文凭证。

但是,对我而言,这似乎还不够:我不希望任何人在他们不应该去的地方闲逛!


6
您可能会在Security.SE上找到许多有趣的帖子。我将注意到一些框架和语言为此提供了专门的支持(例如,.net中的加密配置节)。
布莱恩

9
不幸的是,针对“恶意超级用户”您无能为力。由于您的软件需要访问密钥,因此任何超级用户都需要访问密钥,因为他们能够更改/绕过您可能放置的任何ACL。
DXM 2013年

16
避免必须信任用户的秘密的唯一绝对安全的方法是避免需要这样的秘密。常见的解决方案是在您控制的服务器上运行软件,并且仅分发不受保护的前端,用户可以通过该前端对服务器进行身份验证,然后从服务器使用服务。
阿蒙(Amon)2013年

2
Amon的答案不仅限于用户,还包括任何客户。DXM还提出了一个观点,即您无法保护系统免受想要篡改它的人的侵害,并且您不应该花费精力使他们难以这样做。而是将精力消耗在产品上,这样他们就没有兴趣了
Kevin

3
对于恶意客户端,您能做的最好的事情就是将它们限制在定义良好的服务API上,而不是直接授予他们对数据库的访问权限。除此之外,您实际上无法做任何事情,因为您无法在客户端中隐藏秘密。
CodesInChaos 2013年

Answers:


25

首先,我不会将自己称为安全专家,但是我一直处于必须回答这个问题的位置。我发现的结果使我有些惊讶:没有一个完全安全的系统。好吧,我想一个完全安全的系统就是所有服务器都被关闭的系统:)

当时有人与我合作,描述了设计一种提高入侵者安全标准的安全系统。因此,安全的每一层都减少了攻击的机会。

例如,即使您可以完全保护私钥,该系统也不是完全安全的。但是,正确使用安全算法并及时更新补丁程序可以提高标准。但是,是的,足够强大且有足够时间的超级计算机可以破坏加密。我相信所有这些知识都可以理解,因此我将回答这个问题。

问题很明确,因此我将首先尝试解决您的每一个问题:

假设密钥受文件系统的安全模型保护;但是(恶意)超级用户或不提供这种保真度的平台又如何呢?

是的,如果您使用诸如Windows密钥库之类的东西或使用密码加密的TLS私钥,则会向拥有私钥密码(或访问权限)的用户公开。但是,我认为您会同意提高标准。文件系统ACL(如果正确实施)可以提供很好的保护。您可以亲自审核并了解您的超级用户。

或将密钥硬编码到软件二进制文件中,但始终可以将其反编译,那么开源软件或解释代码又如何呢?

是的,我已经在二进制文件中看到了硬编码的密钥。再次,这确实提高了标准。攻击该系统的人(如果是Java)必须了解Java会生成字节码(等),并且必须了解如何将其反编译。如果您使用的是直接写入机器代码的语言,则可以看到这将标准提高了一些。它不是理想的安全解决方案,但可以提供一定程度的保护。

如果生成了密钥,则此类算法将需要确定性(大概),然后将相同的问题应用于种子。

是的,从本质上讲,该算法将成为用于创建私钥的私钥信息。因此,现在需要对其进行保护。

因此,我认为您已经确定了任何安全策略的核心问题,即密钥管理。制定密钥管理策略对于提供安全的系统至关重要。而且,这是一个相当广泛的话题

因此,问题是,您的系统(以及私钥)需要达到多安全?您的系统中需要提高多高的门槛?

现在,如果您愿意付款,那么会有一些人为此提供解决方案。我们最终使用了HSM(硬件安全模块)。它基本上是一个防篡改服务器,其中包含硬件密钥。然后,可以使用此密钥创建用于加密的其他密钥。这里的想法是(如果配置正确),密钥永远不会离开 HSM。HSM花费很多。但是在某些企业(可以说保护信用卡数据)中,数据泄露的成本要高得多。因此,有一个平衡点。

许多HSM使用功能维护和管理中的密钥卡。一定数量的钥匙卡(假设9张中的5张)必须物理地放入服务器中才能更改密钥。因此,这仅通过在超级用户的法定人数合流时才允许违规,从而将门槛提高得相当高。

可能有一些软件解决方案可以提供与HSM类似的功能,但是我不知道它们是什么。

我知道这只能回答问题,但是我希望这会有所帮助。


2
“好吧,我想一个完全安全的系统就是关闭所有服务器的系统”,并且没有办法打开它们的电源。
StingyJack

2

您想做的事无法完成。

假设密钥受文件系统的安全模型保护;但是(恶意)超级用户或不提供这种保真度的平台又如何呢?

基本上,您希望保护自己免受恶意攻击。在您的模型中,有时某人将有权访问密钥。如果那个人是恶意的怎么办?如果您是恶意的怎么办?看到,您陈述的问题是无法解决的,除非根本没有密钥。

因此,不要使用数据库凭据,而要使用其他身份验证机制。但是无论如何,某人有时需要访问数据,并且某人可能是恶意的。


2

这是在其创建时无法真正解决的问题之一。我们必须退一步,回到一些基本哲学上,并遵循级联,以期寻求解决方案。

第一个理念是“永远不要信任客户”,而密切相关的“如果您真的想保守秘密,就不要告诉任何人!”

正如您提到的,一个简单的示例是数据库凭据。显然,您希望您的客户端可以访问它,但没有任何随机的Internet陌生人,因此您需要某种身份/验证/登录系统。但是,隐藏此秘密的核心前提是一个问题:如果用户本身必须拥有一个秘密,但是您不希望他们知道该秘密是什么,则您所能做的就是隐藏它或使他们难以打开“秘密包裹”。但是他们仍然可以找到答案,因此您最好有一个备份计划!

最简单的解决方案是“不要那样做”。使用用户自己的帐户凭据来允许客户端级别访问该软件的数据库,仅此而已。如果客户端变得恶意,最坏的情况应该是客户端可以破坏自己的数据。而已。现在,您的数据库和系统最多应包含来自该客户端的垃圾条目,仅用于该客户端,没有其他人(包括您)遭受混乱。

在特定的用例中,您只希望部署的软件执行某项操作,而世界上没有所有人都可以连接并执行相同的工作,但是为此,您只是隐藏了秘密,而这样做的唯一正当理由只是为了减少头痛或系统活动。如果您的隐藏信息成为常识,那么最好不要打破游戏规则,只是在最讨厌的情况下。

如果您使用的是狭窄的用例之一,那就只是迷惑了,这全是要有创造力。实际上,这很像Code Golf,但您是创造难题的人。这就是全部-一个难题。而且人们喜欢解决难题,因此,再一次,当有人弄清楚它时,最好还是没问题。

但对于大多数的世界上的事,它只是最好的,而不必担心保守秘密操作用户。相反,最佳实践是仅允许用户使用该秘密,让他们有责任保护该秘密(例如,其用户名和密码),并限制如果秘密泄露或滥用该秘密所带来的负面风险。

在真正的“密钥管理”加密/安全性上下文中,“将私钥存储在何处”的答案是“其他地方!” 加密是点对点保护,公私钥加密旨在保护随时间和空间传输的信息。私钥本质上很容易受到攻击,因此保护它并不是真正的重叠加密问题-它可以完全防止访问。而且,如果系统必须访问它,那么系统本身也必须受到保护-并且您不能在客户端计算机上执行此操作。他们始终可以运行VM,转储RAM,嗅探其网络流量,安装代理或虚拟NIC,反编译可执行文件...不要自愿参与这场松懈的战斗。

现在,如果您需要执行DRM之类的操作,实际上需要基于控制软件本身的使用来存储机密,那完全是另一种情况


TLDR:不要对用户保密,而要与用户保密。


1

我当前使用的系统之一就是这种方式。

  • 我从身份验证服务的登录表单开始。它使用两因素身份验证来确保我是我声称的身份。
  • 我收到一个临时SSL证书,可以用来访问受保护的服务。该服务会跟踪其接受的证书。
  • 我的交易已通过此证书从窃听中加密。尝试破解它不是很有用,因为它将过期。
  • 证书会很快过期(几个小时后),但是不会很快过期,因此我不需要为每次交互都提供密码。
  • 该证书可以在另一侧立即吊销。

当然,受保护的服务在我无法到达的地方运行。它可以在我的计算机上以其他帐户运行(并且可能在容器中),但是我拥有超级用户特权,因此可以尝试规避这些限制。

基本上,如果您有恶意的超级用户,则所有选择都将关闭。而且,您应该在威胁模型中假设存在恶意超级用户。

因此,您需要将受保护的服务与客户端可访问的计算机隔离开。将受保护的服务移至只能通过网络访问的计算机。将您的客户端放置到虚拟机上,以防止它们延伸到运行受保护服务的物理机的其余部分。

如果您的受保护服务不是很宝贵,无法执行此类措施,请使用操作系统为您提供的任何加密密钥存储:Windows,Linux和OSX都有密钥环实现。


-1

在我看来,保持此安全性的唯一方法是使用密码来加密密钥/密码以进行解锁。这样,必须在每次启动或使用密码时都给出密码短语。不太有用。

另一种方法可能是使安全系统成为其自身的数据库帐户。扩展性不是很好...

如果系统上的每个用户都有自己的数据库帐户,并且这些帐户是预先创建的,则应用程序无权代表用户在数据库中创建帐户,那么您可能会很接近。也不是一个好的解决方案,因此我想您必须对配置文件进行非常严格的读取访问,并信任您的超级用户。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.