验证散列密码不起作用 [英] Verification of Hashing password is not working

查看:165
本文介绍了验证散列密码不起作用的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我提出了一个问题,那就是我得到了很多很好的反馈,并提供了一个很好的答案。我认为我对2次哈希值的验证检查做错了。也许在循环中的代码是好的,但我的代码与理解字节和base64等是问题?

这是原始问题。
密码散列 - 为什么使用盐60,000次



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



代码

  public string BuildVerify()
{

string password =;
string salt =;
byte []结果;


使用(var sha256 = SHA256.Create())
{
password =hovercraft;

//步骤1:您可以使用RNGCryptoServiceProvider来获得值得使用
的密码var passwordHashing = new PasswordHashing();
salt = passwordHashing.CreateRandomSalt();

//步骤2
字符串哈希=
Convert.ToBase64String(sha256.ComputeHash(Encoding.UTF8.GetBytes(salt + password)));

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

//步骤4
(int i = 0; i <60000; i ++)
{
结果=
sha256.ComputeHash(编码.UTF8.GetBytes(salt + Convert.ToBase64String(result)));
}
}


// TESTING VERIFY this works ..

字符串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;



$ b public class PasswordHashing
{

public string CreateRandomSalt()
{
string password =;
password = HashPassword.CreateSalt(8)+=;
password = password.Replace(/,c);
返回密码;



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

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

更新 - 问题



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

  //这应该存储在数据库中,例如哈希结果
var newsalt = SOPasswordHasher.GetSalt();

//我们计算散列,然后存储结果。下一次你想认证某人
//你必须重新使用相同的盐并重新计算散列,然后比较
//存储的散列与新的散列
var result = Convert。 ToBase64String(SOPasswordHasher.Hash(hovercraft,newsalt));

字符串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>
///密码哈希
///< / summary>
///< param name =password>您要散列的密码< / param>
///< param name =salt>(crypto-secure)随机值的字节数组< / param>
///< param name =iterations>迭代次数。默认值是60,000< / param>
///<返回>包含散列密码的字节数组< /返回>
$ b $ public static byte [] hash(string password,byte [] salt,int iterations = 60000)
{
using(var sha256 = SHA256.Create())
{
byte [] passwordBytes = Encoding.UTF8.GetBytes(password);

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

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

//步骤4
for(int i = 0; i {
result =
sha256.ComputeHash(salt .Concat(结果).ToArray());
}

返回结果;


$ b $ public static byte [] GetSalt(int size = 32)
{
byte [] salt = new byte [size];
using(var cryptoServiceProvider = new RNGCryptoServiceProvider())
{
cryptoServiceProvider.GetBytes(salt);
}
返回盐;


$ / code $ / pre

以下是一个用法示例:$ / $>

  //这应该存储在数据库中,例如哈希结果
var salt = SOPasswordHasher.GetSalt();

//我们计算散列,然后存储结果。下一次你想认证某人
//你必须重新使用相同的盐并重新计算散列,然后比较
//存储的散列与新的散列
var result = Convert。 ToBase64String(SOPasswordHasher.Hash(hovercraft,salt));

重要提示:我不保证此代码可安全使用,因为我是不是安全专家。布鲁斯·施奈尔说得最好:业余爱好者制作业余密码学


I have asked a question of which I did get a lot of great feedback, along with a good answer. I assume that I am doing something wrong with my verification check of the 2 hashes. Perhaps the code in the loop is fine, but my code with understanding of bytes and base64 etc. is the problem?

Here is the original question. Password Hashing - Why salt 60,000 times

Problem is these hashes do not match if (resultHash.Equals(hashPassword))

Code

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

Update - issue

Ok, I'm using the code from the answer, but obviously my assumptions are not correct as I cannot use my code to verify

            // 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 
            }

解决方案

Here's a reusable class that you can use (relying less on converting to 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;
    }
}

and here's a usage example:

// 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));

Important: I make no guarantee that this code is safe to use since I'm not a security expert. Bruce Schneier said it best: "Amateurs Produce Amateur Cryptography"

这篇关于验证散列密码不起作用的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆