在创建帐户时,如何将密码存储在内存中?

时间:2009-03-14 16:45:50

标签: java security hash passwords

我们的基于网络的应用程序将用户帐户绑定到用户,并在帐户创建期间指定密码。对于Java,在将哈希值保存在数据库中之前,如何安全地处理密码。

更具体地说,如何确保持有密码的字符串在足够短的时间间隔内被垃圾收集?

6 个答案:

答案 0 :(得分:6)

如果您有可能(在Web应用程序中可能很难),最好将密码存储在字符数组中,而不是将它们存储在字符串中。如果您已完成存储密码,则可以使用Array.fill()将其覆盖在内存中,并通过丢弃它来为垃圾收集器提供引用:

Arrays.fill(password, ' ');
password = null;

我只是注意到将密码置零会有点偏执,但如果它让你放心,你可以这样做:)

答案 1 :(得分:5)

您不使用String。使用char []然后在完成时覆盖char []。

在垃圾收集方面绝对没有保证(除了终结器将在收集对象之前运行)。 GC可能永远不会运行,如果它运行它可能永远不会GC其中有密码的字符串。

答案 2 :(得分:3)

如果在客户端创建哈希,则不需要考虑此问题。普通密码永远不会提交给服务器。

答案 3 :(得分:2)

两个词:本地范围。密码处理的声明变量需要具有绝对最小的范围。

一旦变量超出范围,对象就有资格进行垃圾收集。

通常,你会从请求中挑选出来的东西。您需要一个非常非常小的事务来接受请求,哈希密码,持久化并重定向。然后,您重定向的页面可以获取内容并执行作为应用程序一部分的所有“其他”处理。

答案 4 :(得分:1)

无法保证在Java中从内存中删除明文密码。

然而,黑客不需要访问程序的内存来获取明文密码。有更简单的方法(例如嗅探数据包),所以任何人都不太可能依赖这种方法。

最好的方法是让客户端加密密码,如@ Mork0075所示。但是,虽然这意味着您无法轻松获取密码,但程序仍然可以获取密码的加密版本,因此假装是用户。解决这个问题的方法是使用SSL加密整个连接。

所有这些都是学术性的,因为黑客最简单的方法是监视数据包的数据包并获取数据库的密码。我怀疑直接访问您的数据库更关注......或者可能不是。 ;)

答案 5 :(得分:0)

使用密码质询:

  1. 服务器选择质询值并将其发送到客户端
  2. 服务器使用密码和挑战执行单向翻译,例如。 MD5(CONCAT(challenge, password))并将其分配给会话。
  3. 纯文本密码现已超出范围,可以进行垃圾回收。
  4. 客户端也执行相同的转换并将结果发送到服务器。
  5. 如果服务器和客户端选择相同的最终值,则会对客户端进行身份验证。
  6. 此方法可以防止重播攻击,但要求质询值非常难以预测(随机),而且不经常重复使用(长)。

    纯文本密码仅在处理初始连接请求期间 - 而不是在身份验证期间。单向转换结果在范围内(不是垃圾收集)有多长并不重要,因为它几乎没有重放值。