繁体   English   中英

验证哈希密码不起作用

[英]Verification of Hashing password is not working

我问了一个问题,我的确得到了很多好评,并给出了很好的答案。 我假设我对2个哈希的验证检查做错了。 也许循环中的代码很好,但是我的理解字节和base64等的代码是问题吗?

这是原始问题。 密码哈希-为什么加盐60,000次

问题是if (resultHash.Equals(hashPassword))这些哈希值不匹配

public string BuildVerify()
{

    string password = "";
    string salt = "";
    byte[] result;


    using (var sha256 = SHA256.Create())
    {
        password = "hovercraft";

        // step 1: you can use RNGCryptoServiceProvider for something worth using
        var passwordHashing = new PasswordHashing();
        salt = passwordHashing.CreateRandomSalt();

        // step 2
        string hash =
           Convert.ToBase64String(sha256.ComputeHash(Encoding.UTF8.GetBytes(salt + password)));

        // step 3
        result = sha256.ComputeHash(Encoding.UTF8.GetBytes(salt + hash));

        // step 4
        for (int i = 0; i < 60000; i++)
        {
            result =
             sha256.ComputeHash(Encoding.UTF8.GetBytes(salt + Convert.ToBase64String(result)));
        }
    }


    // TESTING  VERIFY this works ..

    string SaltAndPwd = string.Concat(password, salt);
    SHA256 sha2 = SHA256Managed.Create();
    byte[] buff = sha2.ComputeHash(Encoding.Unicode.GetBytes(SaltAndPwd));
    string resultHash = Convert.ToBase64String(buff);
    string hashPassword = Convert.ToBase64String(result);

    if (resultHash.Equals(hashPassword))
    {
        // perfect 
    }





    return "";

}


public class PasswordHashing
{

     public string CreateRandomSalt()
     {
        string password = "";
        password = HashPassword.CreateSalt(8) + "=";
        password = password.Replace("/", "c");
        return password;
     }

  }

public static string CreateSalt(int size)
{
    RNGCryptoServiceProvider rng = new RNGCryptoServiceProvider();

    byte[] buff = new byte[size];
    rng.GetBytes(buff);
    return Convert.ToBase64String(buff);
}

更新-问题

好的,我正在使用答案中的代码,但是显然我的假设是不正确的,因为我无法使用我的代码进行验证

            // This should be stored in your DB for example along with the hash result
            var newsalt = SOPasswordHasher.GetSalt();

            // We calculate the hash then store the result. Next time you want to authenticate someone
            // You'll have to reuse the same salt and recalculate the hash then compare 
            // the stored hash with the new one
            var result = Convert.ToBase64String(SOPasswordHasher.Hash("hovercraft", newsalt));

            string SaltAndPwd = string.Concat("hovercraft", newsalt);
            SHA256 sha2 = SHA256Managed.Create();
            byte[] buff = sha2.ComputeHash(Encoding.Unicode.GetBytes(SaltAndPwd));
            string resultHash = Convert.ToBase64String(buff);

            if (result.Equals(resultHash))
            {
                // perfect 
            }

这是您可以使用的可重用类(更少依赖于转换为base64):

class SOPasswordHasher
{
    /// <summary>
    /// Password Hasher
    /// </summary>
    /// <param name="password">The password you want to hash</param>
    /// <param name="salt">byte array of (crypto-secure) random values</param>
    /// <param name="iterations">Number of iterations. default is 60,000</param>
    /// <returns>Byte array containing the hashed password</returns>

    public static byte[] Hash(string password, byte[] salt, int iterations = 60000)
    {
        using (var sha256 = SHA256.Create())
        {
            byte[] passwordBytes = Encoding.UTF8.GetBytes(password);

            // step 2
            byte[] hash = sha256.ComputeHash(passwordBytes.Concat(salt).ToArray());

            // step 3
            byte[] result = sha256.ComputeHash(salt.Concat(hash).ToArray());

            // step 4
            for (int i = 0; i < iterations; i++)
            {
                result =
                    sha256.ComputeHash(salt.Concat(result).ToArray());
            }

            return result;
        }
    }

    public static byte[] GetSalt(int size = 32)
    {
        byte[] salt = new byte[size];
        using (var cryptoServiceProvider = new RNGCryptoServiceProvider())
        {
            cryptoServiceProvider.GetBytes(salt);
        }
        return salt;
    }
}

这是一个用法示例:

// This should be stored in your DB for example along with the hash result
var salt = SOPasswordHasher.GetSalt();

// We calculate the hash then store the result. Next time you want to authenticate someone
// You'll have to reuse the same salt and recalculate the hash then compare 
// the stored hash with the new one
var result = Convert.ToBase64String(SOPasswordHasher.Hash("hovercraft", salt));

重要说明:由于我不是安全专家,因此我不保证此代码可以安全使用。 布鲁斯·施耐尔(Bruce Schneier)最好地说: “业余爱好者制作业余密码术”

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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