【问题标题】:How can I SHA512 a string in C#?如何在 C# 中对字符串进行 SHA512 处理?
【发布时间】:2012-07-06 18:28:02
【问题描述】:

我正在尝试编写一个函数来获取一个字符串并像这样对它进行 sha512 处理?

public string SHA512(string input)
{
     string hash;

     ~magic~

     return hash;
}

魔法应该是什么?

【问题讨论】:

    标签: c# hash


    【解决方案1】:

    您的代码是正确的,但您应该处置 SHA512Managed 实例:

    using (SHA512 shaM = new SHA512Managed())
    {
       hash = shaM.ComputeHash(data);
    }
    

    512 位是 64 字节。

    要将字符串转换为字节数组,您需要指定编码。如果要创建哈希码,UTF8 是可以的:

    var data = Encoding.UTF8.GetBytes("text");    
    using (...
    

    【讨论】:

    • 不以任何方式使用 dispose 的示例数量惊人。感谢 using 展示惯用的方式。
    • var data = Encoding.UTF8.GetBytes(foo)代替var data = Encoding.UTF8.GetByteCount(foo)
    • 为什么需要“using”子句?默认的 C# 垃圾收集不会启动并摆脱 shaM 变量吗?为什么需要这样的显式垃圾收集?
    • 不要混淆 carbage 收集和释放/处置未使用的非托管对象。使用“using”确保在 using 块结束时调用 Dispose。这将释放非托管资源 - 否则它们将在 GC 清理对象时释放(并在内部调用终结器)。 SHA512Managed 类是一次性的,所以我更喜欢使用 using。有关 Dispose 模式的更多信息,请查看msdn.microsoft.com/en-us/library/b1yfkh5e(v=vs.110).aspx
    • 在 .NET 6 中它会引发警告 Warning SYSLIB0021 'SHA512Managed' is obsolete: 'Derived cryptographic types are obsolete. Use the Create method on the base type instead.' 如何在 .NET 6 中使用它? stackoverflow.com/questions/70109573/… 中有单独的问题
    【解决方案2】:

    这是我的一个项目:

    public static string SHA512(string input)
    {
        var bytes = System.Text.Encoding.UTF8.GetBytes(input);
        using (var hash = System.Security.Cryptography.SHA512.Create())
        {
            var hashedInputBytes = hash.ComputeHash(bytes);
    
            // Convert to text
            // StringBuilder Capacity is 128, because 512 bits / 8 bits in byte * 2 symbols for byte 
            var hashedInputStringBuilder = new System.Text.StringBuilder(128);
            foreach (var b in hashedInputBytes)
                hashedInputStringBuilder.Append(b.ToString("X2"));
            return hashedInputStringBuilder.ToString();
        }
    }
    

    请注意:

    1. SHA512 对象已被释放(“使用”部分),因此我们没有任何资源泄漏。
    2. StringBuilder 用于高效的十六进制字符串构建。

    【讨论】:

    【解决方案3】:

    512/8 = 64,所以 64 确实是正确的大小。也许您想在 SHA512 算法之后将其转换为十六进制

    另请参阅:How do you convert Byte Array to Hexadecimal String, and vice versa?

    【讨论】:

    • 是的,你完全正确。我只是用一个在线生成器来比较,它是十六进制的。谢谢:)
    • 该链接不会将字符串转换为字节数组,而是将十六进制字符串转换为字节。要将字符串转换为字节数组,请使用 Encoding.UTF8.GetByteCount("text")
    • @CarstenSchütte 好吧,UTF-8 是用于文本编码的,与这个问题无关。无论哪种方式,GetByteCount 都不会将字符串转换为字节数组。它只会得到字节数组的 length
    • @CarstenSchütte 哦,等等。我想我知道你的意思。你说的是获取初始的“数据”变量,对吧?在这种情况下,是的,UTF-8 很好。不过,GetByteCount 仍然不是合适的函数。
    • @luiscubal:抱歉,GetByteCount 是我的错(以及复制/粘贴错误)。当然你需要使用 GetBytes() 来获取数据。
    【解决方案4】:

    除了使用 System.Security.Cryptography 的 WinCrypt-API,您还可以使用 BouncyCastle:

    public static byte[] SHA512(string text)
    {
        byte[] bytes = System.Text.Encoding.UTF8.GetBytes(text);
    
        Org.BouncyCastle.Crypto.Digests.Sha512Digest digester = new Org.BouncyCastle.Crypto.Digests.Sha512Digest();
        byte[] retValue = new byte[digester.GetDigestSize()];
        digester.BlockUpdate(bytes, 0, bytes.Length);
        digester.DoFinal(retValue, 0);
        return retValue;
    }
    

    如果您需要 HMAC 版本(向哈希添加身份验证)

    public static byte[] HmacSha512(string text, string key)
    {
        byte[] bytes = Encoding.UTF8.GetBytes(text);
    
        var hmac = new Org.BouncyCastle.Crypto.Macs.HMac(new Org.BouncyCastle.Crypto.Digests.Sha512Digest());
        hmac.Init(new Org.BouncyCastle.Crypto.Parameters.KeyParameter(System.Text.Encoding.UTF8.GetBytes(key)));
    
        byte[] result = new byte[hmac.GetMacSize()];
        hmac.BlockUpdate(bytes, 0, bytes.Length);
        hmac.DoFinal(result, 0);
    
        return result;
    }
    

    【讨论】:

    • BouncyCastle 是什么?
    • @MikaelDúiBolinder:Bouncy Castle Crypto API 由澳大利亚慈善机构 Bouncy Castle Inc. 负责照料和喂养 Bouncy Castle API。 bouncycastle.org
    【解决方案5】:

    您可以尝试以下几行:

    public static string GenSHA512(string s, bool l = false)
    {
        string r = "";
    
        try
        {
            byte[] d = Encoding.UTF8.GetBytes(s);
    
            using (SHA512 a = new SHA512Managed())
            {
                byte[] h = a.ComputeHash(d);
                r = BitConverter.ToString(h).Replace("-", "");
            }
    
            r = (l ? r.ToLowerInvariant() : r);
        }
        catch
        {
    
        }
    
        return r;
    }
    
    1. 放在最后
    2. 很安全
    3. 支持小写

    【讨论】:

      【解决方案6】:

      我不确定你为什么期待 128。

      一个字节中有 8 位。 64 字节。 8 * 64 = 512 位哈希。

      【讨论】:

        【解决方案7】:

        来自MSDN Documentation:
        SHA512Managed 算法的哈希大小为 512 位。

        【讨论】:

          【解决方案8】:

          您可以使用 System.Security.Cryptography.SHA512 类

          MSDN on SHA512

          这是一个示例,直接来自 MSDN

          byte[] data = new byte[DATA_SIZE];
          byte[] result;
          SHA512 shaM = new SHA512Managed();
          result = shaM.ComputeHash(data);
          

          【讨论】:

            【解决方案9】:

            保持简单:

            using (SHA512 sha512 = new SHA512Managed())
            {
                password = Encoding.UTF8.GetString(sha512.ComputeHash(Encoding.UTF8.GetBytes(password)));
            }
            

            【讨论】:

              【解决方案10】:
              UnicodeEncoding UE = new UnicodeEncoding();            
                      byte[] message = UE.GetBytes(password);
                      SHA512Managed hashString = new SHA512Managed();
                      string hexNumber = "";
                      byte[]  hashValue = hashString.ComputeHash(message);
                      foreach (byte x in hashValue)
                      {
                          hexNumber += String.Format("{0:x2}", x);
                      }
                      string hashData = hexNumber;
              

              【讨论】:

                【解决方案11】:

                我用了以下

                public static string ToSha512(this string inputString)
                {
                        if (string.IsNullOrWhiteSpace(inputString)) return string.Empty;
                        using (SHA512 shaM = new SHA512Managed())
                        {
                            return Convert.ToBase64String(shaM.ComputeHash(Encoding.UTF8.GetBytes(inputString)));
                        }
                }
                

                【讨论】:

                  猜你喜欢
                  • 2019-09-19
                  • 2011-04-25
                  • 1970-01-01
                  • 2012-05-06
                  • 2021-09-19
                  • 2018-11-08
                  • 2011-08-24
                  • 1970-01-01
                  • 1970-01-01
                  相关资源
                  最近更新 更多