2010-03-19 71 views
3

我接管了以前的開發人員編寫的系統。系統有管理員批准用戶帳戶,當他們這樣做時,系統使用以下方法散列密碼並將其保存到數據庫。它將未加密的密碼發送給用戶。當用戶登錄時,系統使用完全相同的方法來散列用戶輸入的內容並將其與數據庫值進行比較。當數據庫條目與用戶輸入的數據不匹配時,我們遇到了幾次問題。所以看起來該方法並不總是散列值相同。有誰知道這種哈希方法不可靠嗎?如何使它可靠?謝謝。散列密碼給出不同的結果

private string HashPassword(string password) 
    { 
     string hashedPassword = string.Empty; 

     // Convert plain text into a byte array. 
     byte[] plainTextBytes = Encoding.UTF8.GetBytes(password); 

     // Allocate array, which will hold plain text and salt. 
     byte[] plainTextWithSaltBytes = 
       new byte[plainTextBytes.Length + SALT.Length]; 

     // Copy plain text bytes into resulting array. 
     for(int i = 0; i < plainTextBytes.Length; i++) 
      plainTextWithSaltBytes[i] = plainTextBytes[i]; 

     // Append salt bytes to the resulting array. 
     for(int i = 0; i < SALT.Length; i++) 
      plainTextWithSaltBytes[plainTextBytes.Length + i] = SALT[i]; 

     // Because we support multiple hashing algorithms, we must define 
     // hash object as a common (abstract) base class. We will specify the 
     // actual hashing algorithm class later during object creation. 
     HashAlgorithm hash = new SHA256Managed(); 

     // Compute hash value of our plain text with appended salt. 
     byte[] hashBytes = hash.ComputeHash(plainTextWithSaltBytes); 

     // Create array which will hold hash and original salt bytes. 
     byte[] hashWithSaltBytes = new byte[hashBytes.Length + 
              SALT.Length]; 
     // Copy hash bytes into resulting array. 
     for(int i = 0; i < hashBytes.Length; i++) 
      hashWithSaltBytes[i] = hashBytes[i]; 

     // Append salt bytes to the result. 
     for(int i = 0; i < SALT.Length; i++) 
      hashWithSaltBytes[hashBytes.Length + i] = SALT[i]; 

     // Convert result into a base64-encoded string. 
     hashedPassword = Convert.ToBase64String(hashWithSaltBytes); 

     return hashedPassword; 
    } 

回答

1

如果過程不使用任何隨機決策(即,它是完全確定的),以及所使用的算法的實現是相同的(他們應該是 - SHA256應該作用完全到處都是一樣的,Base64字符串也是一樣),那麼算法本身「不會散列相同的值」是非常不可能的。

如果你不能重現錯誤(意思是:找到某個值,當服務器散列時總是產生一個散列值,當客戶端散列時總是產生一個散列值),你應該確保這些值是正確傳輸和接收的。也許客戶端獲得了非哈希密碼?也許服務器正在接收來自客戶端的損壞數據?也許服務器數據庫本身的數據有某種改變? 確保每筆交易都經過驗證,即用戶無法收到損壞的密碼。

4

這個函數做散列加鹽。這是一個技術,以確保它產生不同的散列相同的密碼,並使表查找更困難。

只有當具有相同的鹽值時,散列纔是相同的

有關此技術的詳細信息,請參閱wikipedia http://en.wikipedia.org/wiki/Salt_%28cryptography%29

報價http://msdn.microsoft.com/en-us/magazine/cc164107.aspx

減緩攻擊,使用的鹽。 鹽是在對它們進行哈希處理之前對密碼 進行調整的一種方式,使得攻擊者的預計算字典 無用。這是如何完成的。 無論何時向 數據庫添加條目,您都會計算一個隨機的 字符串以用作鹽。 當你想計算Alice的密碼的散列值時,你可以查詢Alice的帳戶的 值,在密碼前加上 ,並將它們一起散列 。生成的數據庫看起來 這樣的:

<users> 
    <user name='Alice' salt='Tu72*&' password='6DB80AE7...'/> 
    <user name='Bob' salt='N5sb#X' password='096B1085...'/> 
    <user name='Fred' salt='q-V3bi' password='9118812E...'/> 
</users> 

注意,現在還沒有辦法告訴 鮑勃和弗雷德都使用相同的密碼 。請注意,鹽本身並不是祕密 。