2012-06-27 2 views
4

После преобразования некоторых открытых текстовых паролей, хранящихся в SQL с использованием Hashbytes, похоже, не получается .Net для генерации правильного совпадающего хэша..Net SHA1CryptoServiceProvider не соответствует SQL Hashbytes

SQL используется для преобразования паролей:

UPDATE Users 
SET UserPassword = HASHBYTES('SHA1', UserPassword + CAST(Salt AS VARCHAR(36))) 

Теперь код .Net используется для генерации хэша:

Dim oSHA1 As New System.Security.Cryptography.SHA1CryptoServiceProvider 
Dim bValue() As Byte 
Dim bHash() As Byte 

bValue = System.Text.Encoding.UTF8.GetBytes(sPlainTextPass) 
bHash = oSHA1.ComputeHash(bValue) 
oSHA1.Clear() 

Dim sEncryptPass As String = String.Empty 
For i As Integer = 0 To bHash.Length - 1 
    sEncryptPass = sEncryptPass + bHash(i).ToString("x2").ToLower() 
Next 

Несколько добавлены ноты: Соль хранится в базе данных. sPlainTextPass содержит пароль + соль в виде обычного текста. Я пробовал несколько разных кодировок, включая ASCII, UTF7 и UTF8. Поле базы данных - это varchar, который должен соответствовать UTF8 из того, что я понимаю.

Помощь?

+1

Где что соль хранится? –

+0

В базе данных. – carlowahlstedt

+0

Пожалуйста, не используйте одиночную итерацию SHA1 для хэширования паролей. Используйте PBKDF2, bcrypt или scrypt. – CodesInChaos

ответ

2

Вы не можете содержать строку, вы можете использовать только хэш-байты. Поэтому SQL Server и вам нужно использовать кодировку для перевода строки в байты.

SQL Server не поддерживает UTF8. Вам нужно выяснить, что он использует и сопоставить эту кодировку в вашем приложении. Для nvarchar я бы попробовал Encoding.Unicode и проверил это с помощью редких и специальных символов.

В этой теме, по-видимому, есть информация об этой теме, которую я нашел в Google для кодирования «hashbytes»: http://weblogs.sqlteam.com/mladenp/archive/2009/04/28/Comparing-SQL-Server-HASHBYTES-function-and-.Net-hashing.aspx Хотя я должен сказать, что сообщение в блоге содержит очевидные ошибки и не может быть доверено.

+0

Спасибо, я на самом деле изначально нашел этот пост при попытке решить проблему. Когда я снова получу шанс, я рассмотрю преобразование строки SQL в байты перед ее хэшированием. Я дам вам знать, как это получается. – carlowahlstedt

0

Я видел такие вещи, которые случаются раньше с Sybase SQLAnywhere. В зависимости от используемого SQL-db он может солить хэш на своем собственном, и в этом случае вы никогда не получите соответствующий хеш (не зная внутренней работы БД, то есть)

EDIT:

Если вы хотите сравнить пароли, в свете любого внутреннего соления, вы можете отправить хешированный пароль .NET в БД, хэш снова там и проверить равенство с сохраненным значением. Это, конечно, предполагает, что вы сохранили пароль аналогичным образом.

0

Использование NVARCHAR типа вместо VARCHAR в T-SQL, и результаты будут соответствовать, а

0

Я испытал это то же самое ... Я думаю, что он должен делать с утверждением обновления, чтобы получить ваш хэш заселены таблица пользователей.

Я обнаружил, что проблема заключается в типе данных. Если в выражении

UserPassword + CAST(Salt AS VARCHAR(36)) 

колонна UserPassword является NVARCHAR, то результат будет NVARCHAR и другой хэш.

Я исправил свою проблему, выставив выражение, чтобы соединить пароль и соль с varchar.

Хороший тест, чтобы увидеть, если это на самом деле та же проблема, запустив этот ...

SELECT HASHBYTES('SHA1', UserPassword + CAST(Salt AS VARCHAR(36))), 
HASHBYTES('SHA1', CAST(UserPassword + CAST(Salt AS VARCHAR(36))as varchar)) 
FROM Users 
Смежные вопросы