简体   繁体   中英

Validating HMACSHA256 in C#

I'm pretty new to asp.net/c# and i'm trying to recreate the password validation in C#. I have this hash stored in the database: U2zdbUmZXCeOLs0OuS9bhg==7hQ60TTq0ZiT/z+eu4bdzpmBcp5uYa70ZDxQPncEG0c=

The password for this hash is 1234567. This works because I can login with this password in the webapplication.

So if I understand correctly. The hash consists of a base64 encoded salt U2zdbUmZXCeOLs0OuS9bhg== and a password hashed with this salt: 7hQ60TTq0ZiT/z+eu4bdzpmBcp5uYa70ZDxQPncEG0c=

But if I use this example I found on the internet. I don't get the same hash result. I already tried playing with the encoding (resulting in different hashes), but no luck. hashAlgorithmType is set to HMACSHA256 in the web.config. What am I doing wrong?

using System;
using System.Security.Cryptography;
using System.Text;

public class Program
{
    public static void Main()
    {

        var base64Salt = "U2zdbUmZXCeOLs0OuS9bhg==";  
        var base64Hash = "7hQ60TTq0ZiT/z+eu4bdzpmBcp5uYa70ZDxQPncEG0c=";
        // Decode the base64 salt to get the salt byte array
        var saltBytes = Convert.FromBase64String(base64Salt);

        // Provide the user's plain password
        var plaintextPassword = "1234567";

        // Salt the plaintext password, prepend to user's provided password, and then hash
        try
        {
            var hmac256 = new HMACSHA256(saltBytes);
            var hash = Convert.ToBase64String(hmac256.ComputeHash(Encoding.UTF8.GetBytes(plaintextPassword)));   
            Console.WriteLine(base64Salt+hash);
            if (hash == base64Hash)
            {
                Console.WriteLine("Success! Both hashes match!");
            }
            else
            {
                Console.WriteLine("Passwords do not match.");
            }
        }
        catch (Exception e)
        {
            Console.WriteLine("Error!", e.Message);
        }
    }
}

You need to know the right key used and how is the password concatenated with the salt .

Normally, the salt bytes are concatenated with the password bytes, like this:

var password = "1234567";
var passwordBytes = Encoding.UTF8.GetBytes(password);

var salt = "U2zdbUmZXCeOLs0OuS9bhg==";
var saltBytes = Convert.FromBase64String(salt);

var passwordBytesAndSaltBytes = new byte[passwordBytes.Length + saltBytes.Length];

for (int i = 0; i < passwordBytes.Length; i++)
{
    passwordBytesAndSaltBytes[i] = passwordBytes[i];
}

for (int i = 0; i < saltBytes.Length; i++)
{
    passwordBytesAndSaltBytes[passwordBytes.Length + i] = saltBytes[i];
}

but we don't know what were the rules used.

And the secret is well, kept secret, like this:

var secret = "this must be hidden";
var secretBytes = Encoding.UTF8.GetBytes(secret);

var hmac256 = new HMACSHA256(secretBytes);
var hash = Convert.ToBase64String(hmac256.ComputeHash(passwordBytesAndSaltBytes) );

Without seeing the code, unfortunately, I don't think you will be able to replicate it.

Finally got it to work. I found the answer in the source code of Umbraco (I'm using Umbraco as CMS). I thought it was using the default membershipprovider but it wasn't.., Also worth mentioning that the salt was to short for the required key-length. so it was extended.

From the source code I made a working example:

using System;
using System.Security.Cryptography;
using System.Text;

public class Program
{
    public static void Main()
    {
        var bytes = Encoding.Unicode.GetBytes("1234567");
        var saltBytes = Convert.FromBase64String("U2zdbUmZXCeOLs0OuS9bhg==");
        byte[] inArray;
        var hashAlgorithm = HashAlgorithm.Create("HMACSHA256");
        var algorithm = hashAlgorithm as KeyedHashAlgorithm;
                    var keyedHashAlgorithm = algorithm;
                    if (keyedHashAlgorithm.Key.Length == saltBytes.Length)
                    {
                        //if the salt bytes is the required key length for the algorithm, use it as-is
                        keyedHashAlgorithm.Key = saltBytes;
                        Console.WriteLine("length is ok");
                    }
                    else if (keyedHashAlgorithm.Key.Length < saltBytes.Length)
                    {
                        //if the salt bytes is too long for the required key length for the algorithm, reduce it
                        var numArray2 = new byte[keyedHashAlgorithm.Key.Length];
                        Buffer.BlockCopy(saltBytes, 0, numArray2, 0, numArray2.Length);
                        keyedHashAlgorithm.Key = numArray2;
                        Console.WriteLine("salt byte too long");
                    }
                    else
                    {
                        //if the salt bytes is too short for the required key length for the algorithm, extend it
                        Console.WriteLine("salt byte to short");
                        var numArray2 = new byte[keyedHashAlgorithm.Key.Length];
                        var dstOffset = 0;
                        while (dstOffset < numArray2.Length)
                        {
                            var count = Math.Min(saltBytes.Length, numArray2.Length - dstOffset);
                            Buffer.BlockCopy(saltBytes, 0, numArray2, dstOffset, count);
                            dstOffset += count;
                        }
                        keyedHashAlgorithm.Key = numArray2;
                    }
                    inArray = keyedHashAlgorithm.ComputeHash(bytes);

        var hash = Convert.ToBase64String(inArray);
        Console.WriteLine(hash);        
        var base64Hash = "7hQ60TTq0ZiT/z+eu4bdzpmBcp5uYa70ZDxQPncEG0c=";

            if (hash == base64Hash)
            {
                Console.WriteLine("Success! Both hashes match!");
            }
            else
            {
                Console.WriteLine("Passwords do not match.");
            }
    }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM