.Net SHA1CryptoServiceProvider does not match SQL Hashbytes

After converting some plaintext passwords stored in SQL using Hashbytes, it seems that .Net does not work out to create the correct matching hash.

SQL used to convert passwords:

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

Now .Net code used to generate the hash:

 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 

A few added notes: salt is stored in the database. sPlainTextPass contains the password + salt in plain text. I tried several different encodings, including ASCII, UTF7 and UTF8. The database field is varchar, which should match UTF8 from what I understand.

reference

+4
source share
4 answers

You cannot hash a string, you can only use hash bytes. Therefore, SQL Server and you need to use encoding to translate a string into bytes.

SQL Server does not support UTF8. You need to find out what it uses and match this encoding in your application. For nvarchar, I would try Encoding.Unicode and check this with rare and special characters.

There seems to be some information on the Internet about this topic in which I found Googling for "hash byte encoding": http://weblogs.sqlteam.com/mladenp/archive/2009/04/28/Comparing-SQL-Server- HASHBYTES-function-and-.Net-hashing.aspx Although I must say, the blog post contains obvious errors and cannot be trusted.

+2
source

I have seen similar things happen before with Sybase SQLAnywhere. Depending on the SQL-db used, it may salt the hash on its own, in which case you will never get the corresponding hash (without knowing the internal workings of the database, that is)

EDIT:

If you want to compare passwords, in the light of some kind of internal salting, you can send the hashed .NET password to the database, the hash is there again and check the equality with the stored value. This, of course, assumes that you saved the password in the same way.

0
source

Use the nvarchar type instead of varchar in T-SQL, and the results will also match

0
source

I experienced the same thing ... I think it has to do with the update statement to get your hash populated in the users table.

I found the problem with the data type. If in the expression

 UserPassword + CAST(Salt AS VARCHAR(36)) 

UserPassword column is nvarchar, the result will be nvarchar and another hash.

I fixed my problem by highlighting an expression to combine password and salt in varchar.

A good test is to see if this is really the same problem by running this ...

 SELECT HASHBYTES('SHA1', UserPassword + CAST(Salt AS VARCHAR(36))), HASHBYTES('SHA1', CAST( UserPassword + CAST(Salt AS VARCHAR(36))as varchar)) FROM Users 
0
source

All Articles