SQL 2005 MD5哈希和C#MD5哈希

时间:2009-09-20 17:27:04

标签: c# sql sql-server-2005 encryption

我目前有一个遗留数据库(SQL 2005),它为令牌生成哈希字符串。就是这样......

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”

他们显然是不同的。

那么,是否可以一致地进行匹配?

2 个答案:

答案 0 :(得分: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];
}

在您的示例中,您只是多次覆盖数组中的相同位置,而不是从该点开始设置每个项目。

答案 1 :(得分: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 hasher,我得到明显不同的哈希值。

如果我在通过MD5 Hasher之前反转C#字节数组,我会得到SQL生成的相同哈希。