在SQL Server 2012中验证存储的加密密码

时间:2014-12-16 07:55:47

标签: c# asp.net sql-server-2012 sha256

在SQL Server中,我运行一个命令:

Select HASHBYTES('SHA2_256', '12345678') as EncryptedString

它将此字符串0xEF797C8118F02DFB649607DD5D3F8C7623048C9C063D532CC95C5ED7A898A64F作为输出,此字符串包含66个字符。

在同一方面,我试图用C#代码加密密码,使用:

public string GetSHAEncryptedCode(string Text)
{
    //SHA1 sha26 = new SHA1CryptoServiceProvider();
    SHA256 sha26 = new SHA256CryptoServiceProvider();
    byte[] sha256Bytes = System.Text.Encoding.UTF8.GetBytes(Text);
    byte[] cryString = sha26.ComputeHash(sha256Bytes);
    string sha256Str = string.Empty;
    for (int i = 0; i < cryString.Length; i++)
    {
        sha256Str += cryString[i].ToString("X");
    }
    return sha256Str;
}

如果我在C#代码中输入相同的“12345678”,它会返回一个长度为62个字符的字符串,字符串为EF797C8118F02DFB64967DD5D3F8C762348C9C63D532CC95C5ED7A898A64F。现在我如何验证来自sql server的加密字符串和来自C#代码的其他字符串,以便从登录页面登录用户?

1 个答案:

答案 0 :(得分:1)

您的C#格式字符串不正确 - 当十六进制值小于0时,它缺少前导10

相反,您需要使用"X2"作为格式字符串,以便将其填充为2个数字:

public string GetSHAEncryptedCode(string Text)
{
    //SHA1 sha26 = new SHA1CryptoServiceProvider();
    SHA256 sha26 = new SHA256CryptoServiceProvider();
    byte[] sha256Bytes = System.Text.Encoding.UTF8.GetBytes(Text);
    byte[] cryString = sha26.ComputeHash(sha256Bytes);
    string sha256Str = string.Empty;
    for (int i = 0; i < cryString.Length; i++)
    {
        sha256Str += cryString[i].ToString("X2");
    }
    return sha256Str;
}

这会正确返回EF797C8118F02DFB649607DD5D3F8C7623048C9C063D532CC95C5ED7A898A64F,然后您可以将0x添加到开头。

在任何情况下,您都不应该将值转换为字符串。 HASHBYTES()sha256.ComputeHash()都返回字节数组,因此比较它们更有效,更安全。您可以使用this answer中描述的方法来执行此操作。

或者更好的是,我假设您将密码存储在数据库中加密(不是你......?),所以只需将输入值加密到C#中的字节数组,然后将其传递给数据库并使用像

这样的东西

SELECT * FROM users WHERE username = @username AND password = @passwordBytes