2011-03-15 129 views
1

我想散列一个密码并将其保存在数据库中;我知道散列是一个单向过程。我如何检查用户提供的密码和存储在数据库中的密码是否相同?我正在使用MD5,并且当我每次执行散列操作时,我都会得到相同输入的不同值。谁能帮忙?如何在java中使用散列函数来散列密码?

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

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

您能否提供一个错误代码的示例,用于从相同输入生成不同的md5值? – 2011-03-15 03:48:36

+0

我能够哈希值,但我不知道如何使用该值再次比较 – 2011-03-15 03:53:21

+0

/同意Yanick。如果你正确使用MD5,除非输入改变,否则它不会改变。这就是为什么它被用于验证的原因(不是说它不可能破坏它,因为它是,但是...) – corsiKa 2011-03-15 03:53:22

回答

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编码将其编码为字符串,然后保存编码的哈希。

+0

+1为“坏主意”。散列数据应该总是被视为一个不透明的blob,如果你绝对必须的话,你应该只把它变成一个'String'。加密数据也一样。 – 2011-03-15 04:59:01

+0

非常感谢你,如果你有任何有关哈希的教程,请发布它...你提到过有关字符集转换和base64编码,我不知道它,请帮助 – 2011-03-15 05:32:07

0

用途:

import java.security.*; 

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

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

0

这里有几件事情要检查:

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

如果所有这些都正常,每次输入完全相同的哈希应该返回相同的值。

+0

看到上面的代码如果我打印b和b1其显示不同的值。 – 2011-03-15 04:07:16

+0

啊,没看到代码。哦,斯蒂芬的回答对我来说很好。 – DanielGibbs 2011-03-15 09:27:04

0

在最基本的层次上,当使用密码散列函数时,您在最初存储密码时对密码进行散列处理,然后散列任何匹配该原始密码的尝试。

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

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

结合@Password到du.md5(submittedPassword)