如何在java中使用哈希函数来哈希密码?

时间:2011-03-15 03:46:28

标签: java

我正在尝试哈希密码并将其保存在数据库中;我知道哈希是一个单向的过程。如何检查用户提供的密码和存储在数据库中的密码是否相同?我正在使用MD5,当我每次执行散列时,我得到相同输入的不同值。有人可以帮忙吗?

String pass = "wor1ldcup";
    String pass1 = "wor1ldcup";

    DigestUtils du = new DigestUtils();
    byte[] b = du.md5(pass);
    byte[] b1 = du.md5(pass1);

5 个答案:

答案 0 :(得分:5)

您提供的代码基本上是正确的,但需要注意几点:

  1. DigestUtils的方法都是static,因此应调用为:

    byte[] b = DigestUtils.md5(...);
    

    而不是

    DigestUtils du = new DigestUtils();  // wrong ... no need to instantiate
    byte[] b = du.md5(...);              // wrong ... never use an instance to
                                         //           call a static method.
    
  2. 您没有显示比较bb1的方式,但b == b1不起作用,b.equals(b2)也不会...比较参考。您需要致电Arrays.equals(b, b1)

  3. 尝试将MD5哈希转换为字符串是一个坏主意。根据默认字符集,转换可能会变得有损;即不可逆。如果要在数据库中存储MD5哈希,最好使用(例如)base64编码编码为String,并保存编码哈希。

答案 1 :(得分:3)

你真的应该使用bcrypt而不是MD5来存储密码。 Here is an article on why(还有更多)。

jBcrypt library效果很好。

答案 2 :(得分:0)

使用:

import java.security.*;

byte[] password;
MessageDigest messageDigest = MessageDigest.getInstance("MD5");
messageDigest.update(password, 0, password.length);
byte[] passwordHashed = messageDigest.digest();

需要将String转换为byte[]byte[]转换为十六进制或Base64 String

答案 3 :(得分:0)

以下是要检查的一些事项:

  • 您是否在同一案例中比较哈希?即两个版本中哈希的字母数字是小写的吗?
  • 是否有可能从其中一个哈希的前面截断前导?
  • 您使用==比较两个字符串吗?请改用.equals。

如果所有这些都没问题,则每次对于完全相同的输入,散列应该返回相同的值。

答案 4 :(得分:0)

在最基本的级别,当对密码使用散列函数时,您在最初存储密码时散列密码,然后散列任何与原始密码匹配的尝试。

因此,当您尝试验证现有用户的密码时,您的基本查询将使用提交密码的散列版本作为参数。

SELECT * FROM Users where ID = 1234 and Password = @Password

将@Password绑定到du.md5(submittedPassword)