-4

In SQL Server I run a command:

Select HASHBYTES('SHA2_256', '12345678') as EncryptedString

It gives 0xEF797C8118F02DFB649607DD5D3F8C7623048C9C063D532CC95C5ED7A898A64F this string as an output, this string has 66 characters.

On the same side, Itried to encrypt password from C# code, using this:

public string GetSHAEncryptedCode(string Text)
{
    //SHA1 sha26 = new SHA1CryptoServiceProvider();
    SHA256 sha26 = new SHA256CryptoServiceProvider();
    byte[] sha256Bytes = System.Text.Encoding.UTF8.GetBytes(Text);
    byte[] cryString = sha26.ComputeHash(sha256Bytes);
    string sha256Str = string.Empty;
    for (int i = 0; i < cryString.Length; i++)
    {
        sha256Str += cryString[i].ToString("X");
    }
    return sha256Str;
}

Suupose, if I enter same "12345678" in C# code it returns me a string of 62 character long, string is EF797C8118F02DFB64967DD5D3F8C762348C9C63D532CC95C5ED7A898A64F. Now how could i validate the encrypted string coming from sql server and the other string from C# code in order to login the user from login page?

trejder
  • 17,148
  • 27
  • 124
  • 216

1 Answers1

1

Your C# format string is incorrect - it it missing leading 0s when the hex value is less than 10.

Instead you need to use "X2" as the format string so that it is padded to 2 numbers:

public string GetSHAEncryptedCode(string Text)
{
    //SHA1 sha26 = new SHA1CryptoServiceProvider();
    SHA256 sha26 = new SHA256CryptoServiceProvider();
    byte[] sha256Bytes = System.Text.Encoding.UTF8.GetBytes(Text);
    byte[] cryString = sha26.ComputeHash(sha256Bytes);
    string sha256Str = string.Empty;
    for (int i = 0; i < cryString.Length; i++)
    {
        sha256Str += cryString[i].ToString("X2");
    }
    return sha256Str;
}

This correctly returns EF797C8118F02DFB649607DD5D3F8C7623048C9C063D532CC95C5ED7A898A64F and then you can just append 0x to the start.

In any case, you should not really be converting the values to a string anyway. HASHBYTES() and sha256.ComputeHash() both return byte arrays, so it is more efficient and safer to just compare those instead. You can use the methods described in this answer to do that.

Or maybe better still, I assume you are storing the password in the database as encrypted (aren't you...?), so just encrypt the input value to a byte array in C#, then pass that to the database and use something like

SELECT * FROM users WHERE username = @username AND password = @passwordBytes

Community
  • 1
  • 1
Rhumborl
  • 16,349
  • 4
  • 39
  • 45