2012-11-30 50 views
2

我目前正在將傳統的ASP.NET 1.1應用程序轉換爲.NET 4 MVC 3應用程序。C#MD5CryptoServiceProvider

我正在查看密碼加密,並且在舊代碼中使用MD5CryptoServiceProvider編寫了一個例程。

 private string EncryptText(string szText) 
     { 
      try 
      { 
       UTF8Encoding objEncoder = new UTF8Encoding();     
       MD5CryptoServiceProvider objMD5Hasher = new MD5CryptoServiceProvider(); 
       Byte[] btHashedDataBytes = objMD5Hasher.ComputeHash(objEncoder.GetBytes(szText)); 
       string szReturn = objEncoder.GetString(btHashedDataBytes); 
       objEncoder = null; 
       objMD5Hasher = null; 

       return szReturn; 
      } 
      catch 
      {    
       return ""; 
      } 
     } 

我寫了一個快速的.NET 4的控制檯應用程序,並複製這一功能,所以我可以做對當前密碼的比較在數據庫(以確保MD5函數仍然給我相同的輸出)

  string encTxt = encryptor.EncryptText("fbloggsPass12345"); 

      using (SqlConnection conn = new SqlConnection("Server=server;Database=db;User Id=sa;Password=1111;")) 
      { 
       conn.Open(); 
       using (SqlCommand cmd = new SqlCommand()) 
       { 
        cmd.Connection = conn; 
        cmd.CommandType = System.Data.CommandType.Text;     

        cmd.CommandText = "UPDATE SiteUsers SET Token = '" + encTxt + "' WHERE PKey = 10"; 
        if (cmd.ExecuteNonQuery() > 0) 
         Console.WriteLine("Updated"); 
        else 
         Console.WriteLine("Failed"); 

       } 
       conn.Close(); 
      } 

      Console.ReadLine(); 

但是在數據庫中的密碼是目前!?MGF + &>和我得到的輸出是!?MGF + &>,當我在數據庫中存儲轉換成?? ?!??? MGF?+ & ??>

我可以看到的是幾乎相同的,但爲什麼我得到?人物

回答

5

這是第一個問題,至少:

string szReturn = objEncoder.GetString(btHashedDataBytes); 

您正在嘗試使用哈希,就像它是UTF-8編碼的文本。這不是 - 它只是任意的二進制數據。

如果您需要將任意的二進制數據轉換爲文本,您應該使用類似於Base64的東西(例如Convert.ToBase64String)或十六進制。

(此外,我會強烈勸你不要來「處理」在你此刻這樣的方式異常。你爲什麼要隱藏這樣的問題呢?爲什麼你要爲變量null

哦,和不要直接在你的SQL中包含值 - 使用參數化的SQL代替。

最後,我會使用不同的散列算法,尤其是密碼。您是否可以不使用現成的系統進行身份驗證,這實際上是由安全專家開發的?安全是困難的:我們最好把它留給相對較少的人,他們知道如何正確使用它:)查看更多建議的意見。

+0

正如我所說這是一個快速控制檯應用程序來測試功能,而不是生產代碼。 EncryptText函數是從多年前編寫的應用程序複製而來的,錯誤處理將被完全修改。 –

+0

@AndrewRayner:這不會使代碼更好:)基本問題是編碼部分,但值得關注所有其他問題。 –

+0

我同意代碼是垃圾:)我只是想在證明一個概念之前,我們把這個新項目。我會嘗試關於這個問題的建議:)謝謝! –

1

低影響力升級的標準技術是使用舊散列作爲新哈希方案的輸入。這對於正常的MD5哈希來說效果很好。

不幸的是,您通過非二進制安全編碼(UTF8)發送二進制散列。這將每個第二個字符替換爲0xFFFD,實際上將輸出大小減半爲64位。這大大削弱了升級計劃,但並不致命。

我想升級現有的散列爲PBKDF2(legacyHash, salt),然後在用戶登錄替換散列與新的散列PBKDF2(password, salt)不依賴於傳統的方案。幾個月後,所有尚未登錄的用戶都會重置密碼,從而擺脫基於傳統哈希的密碼。

對於新計劃,我會使用在 Rfc2898DeriveBytes Class中執行的PBKDF2-SHA-1。使用足夠的迭代,至少10000。