2011-01-23 50 views
1

我有一個關於鹽的問題。例如,在我們 數據庫中的記錄,看起來像這樣:如何使用哈希算法驗證明文密碼?

Password: YUphoRF70vJEPAOjMmc/9n47hyQ= 
Password Format: 1 
Password Salt: Vx37L8ItQo3rJzx5gRCxTw== 

我試圖驗證此密碼,但我使用的方法是行不通的。

這是方法:

public static string EncodePassword(string pass, string salt) 
{ 
    byte[] bytes = Encoding.Unicode.GetBytes(pass); 
    byte[] src = Encoding.Unicode.GetBytes(salt); 
    byte[] dst = new byte[src.Length + bytes.Length]; 
    Buffer.BlockCopy(src, 0, dst, 0, src.Length); 
    Buffer.BlockCopy(bytes, 0, dst, src.Length, bytes.Length); 
    HashAlgorithm algorithm = HashAlgorithm.Create("SHA1"); 
    byte[] inArray = algorithm.ComputeHash(dst); 
    return Convert.ToBase64String(inArray); 
} 

我將它傳遞這樣的:

string encodedPasswd = Cryptography.EncodePassword(ClearTxtPassword, DbPasswordSalt); 

什麼回來看起來不象在數據庫中的密碼。

我想知道如果還有別的東西我應該對鹽做?是 什麼是存儲在數據庫中,我應該傳遞給EncodePassword方法,或者是 那裏有一個步驟,我應該在將它作爲 參數傳遞之前解碼它?

我只是不知道爲什麼我得到一個密碼不匹配。根據我工作的站點的web.config,它是passwordFormat =「Hashed」,並且DB中的PasswordFormat列表示「1」,所以我知道它是SHA1。

你有什麼想法,爲什麼我沒有得到正確的匹配或如何得到進一步沿着計算出來(是的,我有正確的密碼。)

編輯:

我曾嘗試以下方法更新:

public static string EncodePassword(string pass, string salt) 
{ 
    byte[] bytes = Encoding.Unicode.GetBytes(pass); 
    byte[] src = Convert.FromBase64String(salt); 
    byte[] dst = new byte[src.Length + bytes.Length]; 
    Buffer.BlockCopy(src, 0, dst, 0, src.Length); 
    Buffer.BlockCopy(bytes, 0, dst, src.Length, bytes.Length); 
    HashAlgorithm algorithm = HashAlgorithm.Create("SHA1"); 
    byte[] inArray = algorithm.ComputeHash(dst); 
    return Convert.ToBase64String(inArray); 
} 

針對我目前的DB數據,它仍然是不匹配的。例如,我得到 以下結果:

passwordText = "administrator" 
passwordformat: 1/SHA1 
passwordSaltInDb: "zVhahfmXj9MrOQySyPQ1Qw==" 
passwordInDb = "YZ5xRJkNG9erGStAkWJA3hID9vE=" 


encodedPasswordResults = "DWZ6XRtVMy4l+XSUOKoX8usUOJI=" 

有沒有什麼辦法,有人可以在自己的環境中進行測試,看看爲什麼我收到這種不同的結果?

+0

你不應該*解密*密碼。將輸入密碼的散列/醃製值與存儲的散列/醃製值進行比較。 – 2011-01-23 05:16:49

+0

謝謝科迪 - 同意。那正是我想要做的 - 只是沒有把這個問題描述得很好。嘗試驗證明文密碼。 – 2011-01-23 06:48:40

+0

您確定它只是SHA1的一次迭代嗎?在密碼散列函數中迭代散列數千次是很常見的。 salt和密碼之間是否應該有分隔符? – caf 2011-01-24 02:32:42

回答

0

SHA1不容易解密,這是它用來存儲密碼的原因之一。你爲什麼試圖解密密碼?

1

如果你正在傳遞salt,就像它存儲在數據庫中一樣,那麼你正在處理一個Base-64編碼的字符串。要將其轉換爲byte[]陣列,您應該使用Convert.FromBase64String而不是Unicode.GetBytes。沿着這些路線的東西:

public static string EncodePassword(string pass, string salt) 
{ 
    byte[] bytes = Encoding.Unicode.GetBytes(pass); 
    byte[] src = Convert.FromBase64String(salt); 
    byte[] dst = new byte[src.Length + bytes.Length]; 
    Buffer.BlockCopy(src, 0, dst, 0, src.Length); 
    Buffer.BlockCopy(bytes, 0, dst, src.Length, bytes.Length); 
    HashAlgorithm algorithm = HashAlgorithm.Create("SHA1"); 
    byte[] inArray = algorithm.ComputeHash(dst); 
    return Convert.ToBase64String(inArray); 
} 

順便說一句,雖然你的問題多次提及解密密碼,在我看來,就好像你只是想驗證對存儲的哈希明文密碼。如果是這種情況,那麼上面的代碼應該沒問題。

如果你真的試圖解密存儲的散列,那麼不要打擾!散列不是密碼的加密版本,因此解密是不可能的。