【问题标题】:JAVA - Secure way of retrieving / storing username & password to a server?JAVA - 将用户名和密码检索/存储到服务器的安全方式?
【发布时间】:2016-01-20 05:10:47
【问题描述】:

我有一个用户名和密码组合,我将使用它通过 java 代码访问安全服务器。

我的想法是:

  1. 在外部存储加密凭据
  2. 执行时提示用户输入解密密码
  3. 使用前将解密的凭据直接存储在 char 数组中
  4. 使用凭据连接到数据库
  5. 使用后用零替换 char 数组

这是执行此类任务的推荐方式吗?

我读到凭据应该存储在外部,这些应该如何存储?

【问题讨论】:

  • 数据库的凭据不应该是用户的凭据...它们应该是与数据库对话的应用程序的凭据。
  • 您能详细说明一下吗?与用户相比,应用程序将具有不同的凭据?这是否仍然意味着这些凭据可能会被盗,并且数据库上的数据可能会泄露?
  • 我用我的回答详细说明了这一点,虽然不完整,但更彻底地解决了这个问题。
  • 就您在此处发布的代码而言,我建议您使用代码审查网站:codereview.stackexchange.com。一件事让我立即跳出来,你正在使用“随机”作为你的盐,但“随机”在密码学上并不强。

标签: java encryption passwords


【解决方案1】:

我认为这个描述有几个问题:

  1. 您暗示用户提供的凭据是数据库的凭据。数据库通常存储大量信息,任何个人用户都应该有权访问这些信息。此外,即使您设法在确保数据库的各种表/行具有正确的访问级别方面做到这一点,使最终用户凭据与数据库凭据同义也会极大地阻碍任何需要的自动化服务器端处理。运行用户数据(例如,汇总统计数据、构建模型,甚至在最终用户不在屏幕上的后台代表用户采取行动)。因此,数据库强制执行的访问粒度对应于在您的服务器环境中运行的程序的访问权限更为常见(并且出于所述原因,更可取),这些程序改为检查最终用户凭据。

  2. 您暗示服务器将存储用户的密码。这通常是一种反模式,因为存储密码本身会使用户在受到损害时面临更大的风险(特别是如果该密码已在其他服务上重复使用)。一般来说,系统应该只存储密码(和盐)的 hash - 通常使用 bcrypt - 当用户输入密码时,您可以使用它来确定匹配,而不存储实际密码。

在降低风险方面,需要考虑几个关键事项:

  1. 分段数据并尽可能提供间接层。也就是说,数据库应该与与之对话的应用程序隔离(考虑不同的虚拟机,不同的操作系统用户)。身份验证凭据应该由可能完全独立于其他数据的数据库和服务器应用程序来管理。需要验证用户凭据的程序也不应该真正看到用户凭据或散列密码;他们应该获得由进行身份验证的子系统分发的短期访问令牌。等等。

  2. 渗透测试,渗透测试,渗透测试。第一次你会弄错这个。甚至可能是第二次。通过定期让独立的局外人进行渗透测试,确保在坏人发现和利用它们之前发现(并修复)这些问题。

  3. 自动化您的测试和 QA 流程。经过测试的代码比未经测试的代码安全得多;如果您有以自动化方式运行的单元测试,您更有可能发现安全漏洞,并且您还可以避免代码的安全敏感部分出现回归。

【讨论】:

  • 不确定您是否完全理解我的问题。我的软件需要访问数据库才能读取某些表。与其硬编码数据库的[ip/username/password],我决定用密码加密这些细节会更安全,然后任何需要使用该软件的人都将获得解密密码(用户将受到限制约 2 或 3 名可靠的员工)。
  • 另外值得注意的是,这些员工将无法访问实际的数据库登录信息,这是受限制的信息。
  • @ChickenFeet 这是有道理的,假设您的软件的“用户”实际上是其他程序/开发人员(而不是真正的最终用户)。我总体上同意这个方案。我要做的一个小改动是,运行与该数据库通信的应用程序的人可能需要的不仅仅是数据库的凭据(他们可能还需要 API 密钥和其他敏感信息)。您可能希望检索这些所有类似系统的一部分;您可能还需要单独的“开发”和“生产”版本的身份验证。
  • 好的,谢谢您的回答/反馈:)
  • 在这种情况下我还应该使用盐吗?
猜你喜欢
  • 1970-01-01
  • 2015-07-13
  • 2013-03-05
  • 2012-09-02
  • 2011-03-26
  • 2021-08-16
  • 1970-01-01
  • 2015-06-12
  • 2021-04-25
相关资源
最近更新 更多