Java:这是对BCrypt的好用吗?

我想知道我当前的BCrypt实现是否正确,我知道我没有使用BCrypt.checkpw()这可能导致一个问题,所以这是我在这里validation它的主要原因。

Hasher.java容器类:

 abstract public class Hasher { public static String hash(final char[] input) { String output = Hasher.hash(new String(input)); for (int i = 0; i < input.length; i++) { input[i] = 0; } return output; } public static String hash(final String input) { return BCrypt.hashpw(input, BCrypt.gensalt()); } } 

这里有一个问题:出于安全原因, JPasswordField给了我一个char[] ,但BCrypt.hashpw()只接受字符串。 如何避免String在我的记忆中漂浮?

登录的客户端实现:

 String hashedPassword = Hasher.hash(password); Network.getInstance().send("login " + username + " " + hashedPassword); 

所以哈希通过网络发送,目前网络没有加密,但我打算添加它。

帐户创建时的服务器实现:

 public static Account createAccount(final String username, final String password) { String hashedPassword = Hasher.hash(password.toCharArray()); return new Account(username, hashedPassword); } 

检查密码的服务器实现:

 public boolean checkPassword(final String hashedPassword) { return this.hashedPassword.equals(hashedPassword); } 

this.hashedPassword是服务器内存中的哈希值(来自启动时的数据库)。

我的设置属性:

  • 登录会占用客户端大量时间,因为密码在那里被散列。
  • 创建帐户/更改密码会占用服务器大量时间,因为密码会在服务器上进行哈希处理。
  • validation登录尝试几乎没有时间服务器,因为不需要进行散列。
  • 如果某人掌握了包含哈希值的数据库,那么他需要花费大量时间来破解每个帐户的密码。
  • 我仍然需要为BCrypt.gensalt()找出一个好的工作因素。

请核实我的假设。

问候。

此设置存在一些问题。

1)salt应该是在散列过程中随机生成的值(因为它似乎在您的实现中。由于客户端无法访问存储哈希的数据库,客户端将无法知道创建时使用的salt登录哈希。

2)此实现实际上并未检查客户端传递的密码,它正在检查客户端传递的密码哈希值。 这意味着如果有人获得了哈希数据库,他们可以立即使用这些哈希值登录。 然后不需要破解它们来提取密码,因为你不检查密码。

通过移动所有散列服务器端,可以轻松解决这两个问题。

更新

关于你提到的问题。

1)如果您打算创建安全系统,则应使用SSL / TLS。 在clear中发送密码哈希几乎与在明文中发送密码完全不安全。 两者都是一个糟糕的主意。 使用HTTPS。

2)执行服务器端散列是一种非常普通的做法。 散列过程的计算成本非常高,使得详尽的搜索不切实际,但它不应该妨碍您的身份validation工作流程。 如果您真的担心自己是DoSed,请跟踪给定用户在过去N秒内尝试登录的次数。 如果他们失败了一定次数,请锁定他们的帐户。