首页 > 解决方案 > 散列密码显示奇怪

问题描述

尝试散列字符串密码然后在控制台中显示散列时,我遇到了一种奇怪的行为。

我的代码是:

    static void Main(string[] args)
    {
        string password = "password";

        ConvertPasswordToHash(password);

    }

    private static void ConvertPasswordToHash(string password)
    {
        using (HashAlgorithm sha = SHA256.Create())
        {
            byte[] result = sha.ComputeHash(Encoding.UTF8.GetBytes(password));

            string hashText = Encoding.UTF8.GetString(result);

            Console.WriteLine(hashText);

            StringBuilder sb = new StringBuilder();

            foreach (var item in result)
            {
                sb.Append((char)item);
            }

            Console.WriteLine(sb);
        }
    }

问题有两个方面:

  1. hashTest 和 sb 包含不同的值(在输出之前都是 32 个字符)并且 2)控制台输出甚至更奇怪。它们的长度不是 32 个字符,其次输出略有不同:

在此处输入图像描述

在输出字符串之前检查字符串时,我注意到 hashText 包含例如 \u0004,它可能是某种 unicode 字符,而 sb 根本不包含它(即在将值输出到控制台之前)。

我的问题是:

  1. 哪种方法是从提供的字节数组中获取字符串的正确方法?
  2. 为什么控制台输出不同但只有那么轻微?看起来这不是使用错误编码的错。
  3. 如何将正确的哈希(32 个符号)输出到控制台?我试过在字符串之前添加'@'来取消任何可能的回车等......几乎没有任何结果。

也许我错过了一些明显的东西。谢谢你。

标签: c#

解决方案


正确的逻辑应该如下:

private static void ConvertPasswordToHash(string password)
{
    using (HashAlgorithm sha = SHA256.Create())
    {
        byte[] result = sha.ComputeHash(Encoding.UTF8.GetBytes(password));

        StringBuilder sb = new StringBuilder();

        foreach (var item in result)
        {
            sb.Append(item.ToString("x2"));
        }

        Console.WriteLine(sb);
    }
}

ToString("x2")将字符串格式化为两个十六进制字符。

现场示例:https ://dotnetfiddle.net/QkREkX

另一种方法是将您的byte[]数组表示为 base 64 字符串,StringBuilder不需要。

byte[] result = sha.ComputeHash(Encoding.UTF8.GetBytes(password));
Console.WriteLine(Convert.ToBase64String(result));

推荐阅读