如何在.NET 6中正确计算SHA 512哈希值

18

来自如何在C#中对字符串进行SHA512处理?的.NET 6代码

  var data = Encoding.UTF8.GetBytes("key");
  byte[] hash;
  using (SHA512 shaM = new SHA512Managed())
    hash = shaM.ComputeHash(data);

抛出警告

Warning SYSLIB0021  'SHA512Managed' is obsolete:
'Derived cryptographic types are obsolete.
Use the Create method on the base type instead.'

Visual Studio 2022不提供此代码更改功能。如何在.NET 6中使用正确的代码替换它?

该代码由ASP.NET MVC控制器调用。


4
为什么警告中不建议使用 System.Security.Cryptography.SHA512 创建 SHA512 shaM = SHA512.Create() - Topaco
谢谢,这样就可以消除警告了。您可以将此作为答案编写。 - Andrus
5个回答

19
    public string CreateSHA512(string strData)
    {
        var message = Encoding.UTF8.GetBytes(strData);
        using (var alg = SHA512.Create())
        {
            string hex = "";

            var hashValue = alg.ComputeHash(message);
            foreach (byte x in hashValue)
            {
                hex += String.Format("{0:x2}", x);
            }
            return hex;
        }
    }

如果使用 var hex = new StringBuilder(); 来改进这个答案会怎样? - sitholewb
1
为什么不使用.NET 5中引入的Convert.ToHexString呢? - Thomas Heijtink

9

您可以使用这种方法。

public string GetSha256Hash(string input)
{
    using (var hashAlgorithm = SHA512.Create())
    {
        var byteValue = Encoding.UTF8.GetBytes(input);
        var byteHash = hashAlgorithm.ComputeHash(byteValue);
        return Convert.ToBase64String(byteHash);
    }
}

0
在我的情况下,我正在使用.NET 5中的RNGCryptoServiceProvider,但当我更新到.NET 6时,我收到了相同的警告。在阅读了this issue之后,我将我的代码从以下内容更改为:
public string HashPassword(string plainPassword)
{
    if (string.IsNullOrEmpty(plainPassword))
    {
        throw new ArgumentNullException(nameof(plainPassword));
    }

    var cryptoProvider = new RNGCryptoServiceProvider();
    byte[] salt = new byte[SaltByteSize];
    cryptoProvider.GetBytes(salt);

    byte[] hash = GetPbkdf2Bytes(plainPassword, salt, Pbkdf2Iterations, HashByteSize);

    return $"{Pbkdf2Iterations}:{Convert.ToBase64String(salt)}:{Convert.ToBase64String(hash)}";
}

转换为:

public string HashPassword(string plainPassword)
{
    if (string.IsNullOrEmpty(plainPassword))
    {
        throw new ArgumentNullException(nameof(plainPassword));
    }

    byte[] salt = RandomNumberGenerator.GetBytes(SaltByteSize);
    byte[] hash = GetPbkdf2Bytes(plainPassword, salt, Pbkdf2Iterations, HashByteSize);

    return $"{Pbkdf2Iterations}:{Convert.ToBase64String(salt)}:{Convert.ToBase64String(hash)}";
}

我知道它们不是完全相同的类,但它们有关联。


-1

你也可以根据微软网站上的描述this link,使用以下代码:

// Disable the warning.
#pragma warning disable SYSLIB0001

// Code that uses obsolete API.
//...

// Re-enable the warning.
#pragma warning restore SYSLIB0001

-1

和Sike Mullivan的答案一样,只是稍微简短一些:

    public string CreateSHA512(string strData)
    {
        var message = Encoding.UTF8.GetBytes(strData);
        using var alg = SHA512.Create();

        var hashValue = alg.ComputeHash(message);
        return hashValue.Aggregate("", (current, x) => current + $"{x:x2}");
    }

或者,作为另一种选择,可以使用一行代码:

public string CreateSHA512(string strData) => SHA512.Create().ComputeHash(Encoding.UTF8.GetBytes(strData)).Aggregate("", (current, x) => current + $"{x:x2}");

1
一行代码是不使用的。它在返回时不释放资源。同时文本变量未定义。 - Andrus

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接