2009-09-20 186 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