2011-03-15 128 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)