I am using this queries below to validate a user.
This query works perfectly fine in SQL Server and in my Asp.Net website.
SELECT *
FROM AdminUsers
WHERE username = 'admin' COLLATE SQL_Latin1_General_CP1_CS_AS
AND Password = (SELECT HASHBYTES('SHA1', 'admin123'))
However when I put it in Asp.net/ C# code as :
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 }
This does not match so not sure how to assign the password parameter so it works, just to confirm password entered is correct. And Password
datatype in SQL Server table is VarBinary
.
Any suggestions?
The VARBINARY type is similar to the VARCHAR type, but stores binary byte strings rather than non-binary character strings. M represents the maximum column length in bytes. It contains no character set, and comparison and sorting are based on the numeric value of the bytes.
INSERT INTO #TempTable(PK, VarBinaryColumn) SELECT PK, VarBinaryColumn FROM dbo. YourPermanentTable; If you need to convert the varbinary data back to the original file text format in T-SQL, you can use CAST or CONVERT to convert to varchar or nvarchar as long as the data was originally ASCII or Unicode.
VARBINARY(MAX) - Binary strings with a variable length can store up to 2^31-1 bytes. IMAGE - Binary strings with a variable length up to 2^31-1 (2,147,483,647) bytes.
varbinary [ ( n | max ) ] max indicates that the maximum storage size is 2^31-1 bytes. The storage size is the actual length of the data entered + 2 bytes. The data that is entered can be 0 bytes in length. The ANSI SQL synonym for varbinary is binary varying.
The data type of your @Password
parameter is not correct.
In your first example, 'admin123' is a varchar
ascii string.
In your .net code @Password
is a string, so is set to type nvarchar
unicode string by default. These hash to different values, i.e.:
select hashbytes('SHA1', 'admin123')
select hashbytes('SHA1', N'admin123')
returns
0xF865B53623B121FD34EE5426C792E5C33AF8C227
0xB7BC3A1B04D9E165C6762B0A1CDE5226DF5B6A6A
You need to set it to a 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
and @Password
are both nvarchar
. HASHBYTES
is very sensitive to varchar
vs nvarchar
; in your working example, 'admin123'
is varchar
. You'll need to explicitly specify those parameters as varchar
(by setting .DbType = System.Data.DbType.AnsiString
), or (preferable) use nvarchar
throughout (too late for that if already hashed). Note: HASHBYTES
by itself probably isn't a great choice for cryptography.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With