【问题标题】:Where do you store your secret key in a Java Web Application? [closed]您将密钥存储在 Java Web 应用程序中的什么位置? [关闭]
【发布时间】:2012-12-21 13:30:58
【问题描述】:

密码学是一种广泛采用的技术来确保机密性。不考虑实现缺陷,它有一个关键点:密钥存储。如果密钥被盗,整个系统都会受到威胁。

编辑:

让我指定上下文以使问题不那么广泛:

  1. 这里解决了一个 java web 应用程序
  2. 更具体地说,它使用的是 spring 框架版本 3
  3. spring security 3.1 用于保护应用程序
  4. mysql5 数据库可用
  5. 应用服务器是tomcat6或者tomcat7
  6. 服务器计算机不在我的控制之下

也许问题可以集中在这种情况下,但正如所指出的,密钥存储问题与所采用的技术是横向的。然而,一些库可能会提供可以以某种方式促进工作的特殊功能。 一个明确的观点是,必须在安全性和做实际事情的需要之间找到一个权衡。为了完成分析,很明显,所需的安全级别取决于要保护的信息的价值。想方设法实施超级安全的策略(需要付出很多努力)来保密客户的鞋码是毫无意义的。

在这里,我必须保护电子邮件密码(将存储在数据库中)。我认为这些信息很重要。

我在这里寻找的是合理努力的最佳解决方案。

所以问题很明确:您会将这些信息存储在哪里?

  1. 您是否将其存储在数据库中?所以它应该被加密,这需要另一个密钥(你将第二个密钥存储在哪里?)
  2. 您是否将其存储在.war 包中?您如何防止未经授权访问源?
  3. 您是否采用不同的策略?

我们将不胜感激您制定策略的动机。 谢谢

【问题讨论】:

标签: java web-applications encryption


【解决方案1】:

我冒昧地写一个答案,即使这与 Java Web 应用程序没有任何关系:我认为问题存在于所有平台的微小差异。

基本上有 3 个候选密钥存储,您提到的前 2 个:

  • 数据库
  • 应用程序(“硬编码”)
  • 服务器上运行 WebApp 的其他位置,通常是文件

你已经指出了前两个的弱点,所以不需要重复,我完全同意。

这也是我使用第三个候选人的动机。原因是这样的:

  • 同一应用的不同实例很容易拥有不同的密钥,因此一个妥协不会自动传播到所有其他人
  • 如果服务器以某种方式受到威胁,允许攻击者读取任何文件,那么游戏就结束了:您无法阻止他读取应用程序二进制文件或 DB
  • Web 服务器上的文件系统安全性是一个很好理解的主题
  • 允许完全文件系统访问的入侵在统计上远低于应用程序或数据库入侵

【讨论】:

  • 好的,所以你说要在服务器机器的文件系统中创建一个文件,并在那里以明文形式写入密码。当然,我必须对该文件设置严格的权限(例如,只有“应用程序用户”可以读取它)。一种常见的情况是服务器计算机不受您的控制。管理员用户无论如何都可以做任何事情。也许带有密钥的文件可能会使用客户端密钥进行加密。但这意味着更复杂的架构并不总是可用的。好的,我们不得不相信提供商。
  • 将密钥放入文件(或@AleksanderGralak 建议的容器)中无需额外步骤即可完成,例如使用硬编码密钥加密密钥。流氓管理员与成功的根级攻击者相同:没有什么是安全的
  • 我可以看到使用文件的两个问题:1)如果您的应用程序变得足够大以需要多个负载平衡实例,则您必须保持此文件重复(或更多)并保持同步。 2) 如果您有大量用户,那么搜索文件可能会成为一种负担。我不自称是这方面的专家,但这是我刚才试图为自己解决这个问题时的一些想法。但这是我所见过的少数帖子之一,可以为我提供其他人正在寻找或制定相同解决方案的线索。
  • 您必须保持 所有 文件同步,构成应用程序 - 这里没有什么新鲜事!关于用户数:文件很小,很可能在 RAM(缓存)中,所以没有 IO 问题。此外,您可以在 App 启动时解析它一次并保留解析后的副本!
【解决方案2】:

无论您总是需要将密钥存储在什么地方。即使您决定(这很愚蠢)手动提供密钥,密钥也会驻留在内存中,并且有人可以找到它。

存储位置取决于您的选择。但是,它不应该是纯文本。因此,如果您将密钥存储在数据库中,则在应用程序中使用硬编码的辅助密钥。所以如果入侵者只能访问 db,那么加密的主密钥就会受到保护。

我会进行应用程序配置以将辅助密钥存储在容器中。这样,只有您的应用程序才能访问此属性。因此,攻击者必须控制您的应用程序或容器才能访问该密钥。

所以假设以下场景:

  1. 您的应用程序被黑:攻击者拥有与您相同的权限。可以尝试使用您的 API 来获取敏感信息,而无需使用加密。你的代码会为他们做这件事。下一个选项:她可以尝试获取您的 war 文件或类文件并对其进行反编译以找出硬编码的密钥,或者了解您使用的加密机制。
  2. 只有数据库被黑客入侵:使用不在数据库中的密钥加密数据应该没问题。

为了让攻击者更难。您可以将文件放在文件系统中。如其他答案中所述,为其添加适当的 FS 权限。但另外使用 java 安全管理器来限制对所有 java 类的访问,除了真正需要读取它的类。限制对 jar 和类文件的修改也是一个好主意。

您拥有的锁越多,您就越安全。与标准门锁一样。锁应该来自不同的供应商并具有不同的机制。但最终熟练的窃贼无论如何都会进入。

【讨论】:

  • @Alexsander:你有什么教程可以在java中实现吗?如何在容器中存储辅助密钥以及辅助密钥和主密钥如何加密数据库中的数据。
  • 还有java中如何限制不同用户对文件的文件系统权限?
  • @Alien01 澄清一下。加密整个数据库超出了这个问题的范围,据我所知,它更像是实验性的想法而不是真实的东西。所以在我们的情况下,秘密是电子邮件的密码。因此,您将加密密钥存储在应用程序上下文中:stackoverflow.com/questions/372686/… 然后您使用对称加密来加密密码。现在您可以从 db 中检索密码并对其进行解密并用于访问 SMTP 服务器。
  • @Alien01 如果你真的很偏执,那么你可以在文件系统的某个地方拥有辅助密钥。所以你使用第一个密钥来加密密码,然后你使用辅助密钥来加密已经加密的消息和你存储在数据库中的结果。要取回密码,请以相反的方向进行。为了保护 fs 中的文件访问,您可以将读取选项限制为仅一个类。 Tomcat 权限设置说明:tomcat.apache.org/tomcat-7.0-doc/security-manager-howto.html
【解决方案3】:

文件系统没问题,选择用户权限并在战争中使用授予权限。存在许多安全漏洞,仅开放对数据库或战争内容的访问

【讨论】:

    猜你喜欢
    • 2014-10-02
    • 1970-01-01
    • 2010-09-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-06-29
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多