2009-09-20 206 views
1

我目前有一個遺留數據庫(SQL 2005),用於生成令牌的哈希字符串。它確實是這樣的...SQL 2005 MD5哈希和C#MD5哈希

DECLARE @RowID INT 
DECLARE @hashString VARCHAR(128) 

SET @RowID = 12345 
SET @salt= 0xD2779428A5328AF9 

SET @hashBinary = HASHBYTES(('MD5', @salt + CAST(@RowID AS VARBINARY(30))) 
SET @hashString = sys.fn_varbintohexstr(@hashBinary) 

如果我執行這一點,我在我的哈希值的字符串看起來是這樣的:「0x69a947fd71b853485007f0d0be0763a5」

現在,我需要複製在C#中相同的邏輯,所以我可以刪除生成這些散列的數據庫依賴關係,並且必須向後兼容。

我在C#中實現這樣的:

byte[] saltBytes = BitConverter.GetBytes(0xD2779428A5328AF9); 
byte[] pidBytes = BitConverter.GetBytes(12345); 

byte[] bytesToHash = new byte[saltBytes.Length + pidBytes.Length]; 

for (int i = 0; i < saltBytes.Length; i++) 
{ 
    bytesToHash[i] = saltBytes[i]; 
} 

for (int i = 0; i < pidBytes.Length; i++) 
{ 
    bytesToHash[saltBytes.Length + 1] = pidBytes[i]; 
} 

MD5CryptoServiceProvider hasher = new MD5CryptoServiceProvider(); 
byte[] hashedBytes = hasher.ComputeHash(bytesToHash); 

string hashString = BitConverter.ToString(hashedBytes).ToLower().Replace("-", ""); 

的問題是,我的C#實現生成該散列: 「715f5d6341722115a1bfb2c82e4421bf」

他們顯然是不同的。

那麼,是否有可能一致地進行比賽?

+0

因此,如果我得到12345(作爲int)和「12345」作爲字符串的字節數組,我得到了不同的散列值。另外,如果我創建一個長度爲30的空白字節[像我的SQL在其投影中那樣),我也會得到不同的結果。那麼......是否有一致的方法來做到這一點? – ctorx 2009-09-20 18:08:16

回答

1

我已經解決了這個問題:

如果我這樣做在SQL:

DECLARE @Value INT 
SET @Value = 12345 

SELECT sys.fn_varbintohexstr(CAST(@Value AS VARBINARY(30))) 

我得到這樣的結果:0x00003039

現在,如果我這樣做的C#:

int value = 12345; 
byte[] bytes = BitConverter.GetBytes(value); 
Console.Write(BitConverter.ToString(bytes)) 

我得到這個結果:39-30-00-00

字節看起來是相反的順序。因此,一旦我將這些字節數組應用到MD5散列器,我會得到明顯不同的散列值。

如果我在通過MD5哈希函數之前顛倒了C#字節數組,我得到了由SQL生成的相同哈希。

+0

不錯的抓@Matthew – 2009-09-21 13:25:18

+0

是的,任何想法爲什麼?是顛倒字節順序的SQL,還是它是BitConverter還是我只是消耗太多咖啡因? – ctorx 2009-09-23 21:20:33

3

在我看來,像你的第二個循環中有一個錯誤。嘗試改變「+ 1」到「+ I」 ......

for (int i = 0; i < pidBytes.Length; i++) 
{ 
    // the line below just overwrites the same position multiple times 
    // bytesToHash[saltBytes.Length + 1] = pidBytes[i]; 
    bytesToHash[saltBytes.Length + i] = pidBytes[i]; 
} 

在你的榜樣,你只是覆蓋在陣列多次同樣的位置,而不是從該點向前設置每個項目。

+0

進行此更改會提供不同的哈希值,但它與SQL生成的哈希值不同。 – ctorx 2009-09-20 17:44:23