Search code examples
c#sql-servert-sqlencodinghash

C# Hash SHA256Managed is not equal to TSQL SHA2_256


I am using hashed passwords with a salt (the username).

Problem is that the hashed values of c# are not equal to the initial values I add to the database by a TSQL Script.

TSQL:

UPDATE [Users]
SET Password = HASHBYTES('SHA2_256', 'test123'+UPPER([UserName]))
GO;

C#:

var passBytes = new UnicodeEncoding().GetBytes(pass);
var saltBytes = new UnicodeEncoding().GetBytes(userName.ToUpper());

var dataToHash = new byte[passBytes.Length + saltBytes.Length];
Array.Copy(passBytes, dataToHash, passBytes.Length);
Array.Copy(saltBytes, dataToHash, saltBytes.Length);

var sha = new SHA256Managed();
return sha.ComputeHash(dataToHash);

I guess it has something to do with the encoding. But i have no idea how to fix this.

UserName is varchar(50)

The DB is an existing one so changing the varchar will not be so easy.

I already tried:

UPDATE [Users]
SET Password = HASHBYTES('SHA2_256', N'test123'+UPPER([UserName]))
GO;

Solution

  • If your SQL Server database is configured to use the default collation of SQL_Latin1_General_CP1_CI_AS, then in your C# code, use code page 1252 to convert characters to bytes. Thus, the equivalent of

    HASHBYTES('SHA2_256', 'test123' + UPPER([UserName]))
    

    is

    byte[] data = Encoding.GetEncoding(1252).GetBytes("test123" + userName.ToUpper());
    var sha = new SHA256Managed();
    byte[] hash = sha.ComputeHash(data);