正在C#中验证HMACSHA256

问题描述 投票:0回答:2

我对asp.net/c#相当陌生,我正尝试在C#中重新创建密码验证。我将此哈希存储在数据库中:U2zdbUmZXCeOLs0OuS9bhg==7hQ60TTq0ZiT/z+eu4bdzpmBcp5uYa70ZDxQPncEG0c=

此哈希的密码为1234567。之所以有效,是因为我可以在Web应用程序中使用此密码登录。

所以,如果我理解正确的话。哈希由base64编码的盐U2zdbUmZXCeOLs0OuS9bhg==和以此盐哈希的密码组成:7hQ60TTq0ZiT/z+eu4bdzpmBcp5uYa70ZDxQPncEG0c=

但是如果我使用此示例,我会在互联网上找到。我没有得到相同的哈希结果。我已经尝试过使用编码(导致不同的哈希值),但是没有运气。在web.config中将hashAlgorithmType设置为HMACSHA256。我在做什么错?

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);
        }
    }
}
c# asp.net security hash hmac
2个回答
0
投票
您需要

知道正确的键,并且密码与盐如何连接

通常,盐字节与密码字节连接在一起,如下所示:

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]; }

但是我们不知道使用了什么规则。

这个秘密很好,保守秘密,像这样:

var secret = "this must be hidden"; var secretBytes = Encoding.UTF8.GetBytes(secret); var hmac256 = new HMACSHA256(secretBytes); var hash = Convert.ToBase64String(hmac256.ComputeHash(passwordBytesAndSaltBytes) );

不幸的是,我没有看到代码,所以您不能复制它。

0
投票
终于让它起作用了!我在Umbraco的源代码中找到了答案(我使用Umbraco作为CMS)。我以为它使用的是默认的MembershipProvider,但事实并非如此。还值得一提的是,盐值短于所需的密钥长度,因此它得到了扩展。

根据源代码,我创建了一个有效的示例:

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 to 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."); } } }

© www.soinside.com 2019 - 2024. All rights reserved.