【问题标题】:Generated password hashes are always followed by a '=='生成的密码哈希总是后跟一个'=='
【发布时间】:2017-03-14 02:13:44
【问题描述】:

在我的应用程序中,我有一个散列密码并生成盐的类。出于某种原因,每个哈希似乎总是以双等号 (==) 结尾。

我做错了吗?这些哈希值不安全吗?

应用程序在 c# 和 asp.net 中,生成盐和哈希的代码如下...

public class PasswordService : IPasswordService
{
    private static RandomNumberGenerator random = RandomNumberGenerator.Create();

    public string HashPassword(string salt, string password)
    {
        Rfc2898DeriveBytes hasher = new Rfc2898DeriveBytes(password, Convert.FromBase64String(salt), 10000);

        byte[] hash = hasher.GetBytes(64);

        return Convert.ToBase64String(hash);
    }

    public bool VerifyPasswordHash(string salt, string password, string hash)
    {
        return HashPassword(salt, password) == hash;
    }

    public string GenerateSalt()
    {
        int max_length = 32;

        byte[] salt = new byte[max_length];

        random.GetBytes(salt);

        return Convert.ToBase64String(salt); 
    }
}

谢谢!

【问题讨论】:

标签: c# asp.net hash passwords


【解决方案1】:

当然它会以 == 结尾,您正在编码为 Base64! :)。 Base64 中的所有内容都以 == 结尾。

【讨论】:

  • 这不太正确。有足够多的= 来填充一个块。 (4 个基数 64 个字符 / 3 个字节)(即零个、一个或两个 =
  • 所以这不是我的实现中的错误,而是我的字符串转换的产物?我不明白。 C# 将字符串存储为 16 位 UTF8。这不是可以整除的吗?我认为这里有一些我不明白的地方。
  • 我们所说的(@Tibrogargan 稍微纠正了答案)是使用 Base64,你会用 = 填充块。因此,您可以在 Base64 字符串的末尾以 0、1 或 2 = 结尾。这很正常。
  • @Dabloons - 存储为 UTF-16 的字符串在这里完全无关紧要。首先,您的 Base64 编码器不采用字符串,而是采用原始字节序列。其次,Base64 将 3 个字节的输入转换为 4 个字符的输出。您的输入始终为 64 个字节,因此前 63 个字符始终为 21 个块,剩余 1 个字节。因此,为什么最后会得到两个 ==,因为它填充了 2 个字节以构成第 22 个块。
猜你喜欢
  • 2016-02-06
  • 2015-05-12
  • 2011-06-20
  • 2010-12-03
  • 2017-10-15
  • 2021-05-14
  • 1970-01-01
  • 2015-11-30
相关资源
最近更新 更多