2014-12-15 2 views
7

Я использую эти запросы ниже для проверки пользователя.Запрос SQL Server не подходит для столбца типа varbinary

Этот запрос отлично работает на SQL Server и на моем сайте Asp.Net.

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

Однако, когда я положил его в Asp.net/ C# код, как:

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 Server - VarBinary.

Любые предложения?

+0

Что вы имеете в виду под "не соответствует". –

+0

Как сказал Марк, вы не должны изобретать методы безопасности или наивно реализовывать. SHA1 является быстрым и относительно слабым, поэтому не является хорошим выбором для хэширования паролей. Есть целый набор библиотек, которые могут сделать это для вас в .Net, пожалуйста, используйте их. http://msdn.microsoft.com/en-us/library/system.security.cryptography%28v=vs.110%29.aspx например – Lukos

ответ

7

Неверный тип данных вашего @Password.

В вашем первом примере 'admin123' является строкой ascii varchar.

В вашем .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 } 
+0

Спасибо за то, что один вопрос, читающий комментарии выше, - это слабый подход использовать для установки паролей? – confusedMind

+0

работает отлично. – confusedMind

1

@userName и @Password оба являются nvarchar. HASHBYTES очень чувствителен к varchar vs nvarchar; в вашем рабочем примере 'admin123' - varchar. Вам нужно будет явно указать эти параметры как varchar (путем установки .DbType = System.Data.DbType.AnsiString) или (предпочтительно) использовать nvarchar всюду (слишком поздно для этого, если он уже хэширован). Примечание: HASHBYTES сам по себе, вероятно, не является отличным выбором для криптографии.

Смежные вопросы