在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#代码的其他字符串,以便从登录页面登录用户?
答案 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