【问题标题】:Converting a md5 hash byte array to a string将 md5 哈希字节数组转换为字符串
【发布时间】:2011-01-27 00:00:52
【问题描述】:

如何将哈希结果(字节数组)转换为字符串?

byte[] bytePassword = Encoding.UTF8.GetBytes(password);

using (MD5 md5 = MD5.Create())
{
    byte[] byteHashedPassword = md5.ComputeHash(bytePassword);
} 

我需要将byteHashedPassword 转换为字符串。

【问题讨论】:

  • MD5 已弃用。它本质上是破损的,因为它没有达到抗碰撞或抗原像性的标准。对于密码,最好使用迭代的密钥派生函数,例如 Argon2 或 PDKDF2。

标签: c# hash cryptography md5 cryptographic-hash-function


【解决方案1】:

您可以使用Convert.ToBase64StringConvert.FromBase64String 轻松将字节数组转换为字符串。

【讨论】:

    【解决方案2】:
       public static string ToHex(this byte[] bytes, bool upperCase)
        {
            StringBuilder result = new StringBuilder(bytes.Length*2);
    
            for (int i = 0; i < bytes.Length; i++)
                result.Append(bytes[i].ToString(upperCase ? "X2" : "x2"));
    
            return result.ToString();
        }
    

    然后您可以将其作为扩展方法调用:

    string hexString = byteArray.ToHex(false);
    

    【讨论】:

    • 上壳有什么意义?
    • 一个偏好问题。这就是为什么我在我的方法中添加了一个参数,以便调用者可以选择
    • 已经拥有Convert.ToBase64String(),无需重新发明轮子
    • Base64 字符串更短。它使用字母表中的所有字母、数字和一些标点符号,所以它不是十六进制的。 Base64 使用 4 个字符 3 个字节,而十六进制字符串使用 6 个字符 3 个字节。
    • @Eric:在某些情况下 Base64 不是一个好的选择,因为使用了额外的标点符号(例如在 URL 中传递它)
    【解决方案3】:

    因为它是一个散列,它可能具有无法在普通字符串中显示的值,所以最好的办法是将其转换为 Base64 编码的字符串。

    string s = Convert.ToBase64String(bytes);
    

    并使用

    byte[] bytes = Convert.FromBase64(s);
    

    获取字节。

    【讨论】:

      【解决方案4】:

      好吧,您可以使用带有字节和编码的字符串构造函数,但您可能会很难管理字符串,因为它可能包含许多有趣的字符(空字节、换行符、控制字符等)

      最好的方法是使用 base 64 对其进行编码以获得易于使用的漂亮字符串:

      string s = Convert.ToBase64String(bytes);
      

      然后从那个字符串返回一个字节数组:

      byte[] bytes = Convert.FromBase64String(s);
      

      【讨论】:

        【解决方案5】:

        我一直觉得这样最方便:

        string hashPassword = BitConverter.ToString(byteHashedPassword).Replace("-","");
        

        出于某种奇怪的原因,BitConverter 喜欢在字节之间放置破折号,因此替换只是删除了它们。

        更新: 如果您更喜欢“小写”十六进制,只需执行 .ToLower() 和繁荣。

        请注意,如果您将其作为一个紧密循环和许多操作来执行,这可能会很昂贵,因为至少有两个隐式字符串转换和调整大小正在进行。

        【讨论】:

        • 与@PhilippeLeybaert 解决方案相同,但在一行中。
        【解决方案6】:

        如果您属于“十六进制偏好”阵营,您可以这样做。这基本上是 Philippe Leybaert 答案的最小版本。

        string.Concat(hash.Select(x => x.ToString("X2")))
        

        B1DB2CC0BAEE67EA47CFAEDBF2D747DF

        【讨论】:

          【解决方案7】:

          对于任何感兴趣的人,我创建的一个名为 CryptoStringify 的 Nuget 包允许您使用简洁的语法将字符串转换为散列字符串,而无需使用字节数组:

          using (MD5 md5 = MD5.Create())
          {
              string strHashedPassword = md5.Hash(password);
          }
          

          这是HashAlgorithmKeyedHashAlgorithm 的扩展方法,因此也适用于SHA1、HMACSHA1、SHA256 等。

          https://www.nuget.org/packages/cryptostringify

          【讨论】:

            猜你喜欢
            • 2011-11-15
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2014-08-22
            • 1970-01-01
            • 2022-08-11
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多