SQL Server 查询与变量二进制类型列不匹配

本文关键字:类型 不匹配 二进制 变量 Server 查询 SQL | 更新日期: 2023-09-27 18:34:22

我正在使用下面的查询来验证用户。

此查询在 SQL Server 和我的 Asp.Net 网站中运行良好。

SELECT * 
FROM AdminUsers 
WHERE username = 'admin' COLLATE SQL_Latin1_General_CP1_CS_AS 
  AND Password = (SELECT HASHBYTES('SHA1', 'admin123'))

但是,当我将其放入 C# 代码 Asp.net/时:

dbManager.Command.CommandText = @"SELECT * FROM AdminUsers 
WHERE username= @UserName COLLATE SQL_Latin1_General_CP1_CS_AS AND
Password = (SELECT HASHBYTES('SHA1', @Password))";
dbManager.Command.Parameters.AddWithValue("@userName", username);
dbManager.Command.Parameters.AddWithValue("@Password", password);
reader = dbManager.GetDataReader();
if (reader.Read() == true)
{ //USER VALIDATED }

这不匹配,所以不确定如何分配密码参数以便它工作,只是为了确认输入的密码是正确的。并且Password SQL服务器表中的数据类型为VarBinary

有什么建议吗?

SQL Server 查询与变量二进制类型列不匹配

@Password参数的数据类型不正确。

在您的第一个示例中,"admin123"是一个varchar ascii 字符串。

在 .net 代码中,@Password 是一个字符串,因此默认设置为键入nvarchar unicode 字符串。这些哈希为不同的值,即:

select hashbytes('SHA1', 'admin123')
select hashbytes('SHA1', N'admin123')

返回

0xF865B53623B121FD34EE5426C792E5C33AF8C227
0xB7BC3A1B04D9E165C6762B0A1CDE5226DF5B6A6A

您需要将其设置为 varchar SqlDbType:

dbManager.Command.CommandText = @"SELECT * FROM AdminUsers 
WHERE  username= @UserName COLLATE SQL_Latin1_General_CP1_CS_AS AND
Password=(SELECT HASHBYTES('SHA1',@Password))";
dbManager.Command.Parameters.AddWithValue("@userName", username);
dbManager.Command.Parameters.AddWithValue("@Password", password)
    .SqlDbType = SqlDbType.VarChar;
reader = dbManager.GetDataReader();
if (reader.Read() == true)
{ //USER VALIDATED }

@userName@Password都是nvarcharHASHBYTESvarcharnvarchar非常敏感;在您的工作示例中,'admin123' varchar .您需要将这些参数显式指定为 varchar(通过设置 .DbType = System.Data.DbType.AnsiString ),或者(最好)始终使用 nvarchar(如果已经散列,则为时已晚)。注意:HASHBYTES本身可能不是加密的好选择。