HashAlgorithm.Create 在 C# ASP.NET Core 2 中因 PlatformNotSupportedException 而失败

Posted

技术标签:

【中文标题】HashAlgorithm.Create 在 C# ASP.NET Core 2 中因 PlatformNotSupportedException 而失败【英文标题】:HashAlgorithm.Create fails with PlatformNotSupportedException in C# ASP.NET Core 2 【发布时间】:2019-01-10 23:29:26 【问题描述】:

我有一个 ASP.Net MVC 项目,在使用 HashAlgorithm 时可以正常工作,但我试图在 ASP.NET Core 2 中复制同一个项目,但出现以下错误:

System.PlatformNotSupportedException HResult=0x80131539 Message=此平台不支持操作。 Source=System.Security.Cryptography.Primitives 堆栈跟踪: 在 System.Security.Cryptography.HashAlgorithm.Create(String hashName) 在 Hash.Program.EncodePassword(String pass, String salt)

我的代码:

public static string GeneratePassword(int saltlength) //length of salt

    const string chars = "abcdefghijkmnopqrstuvwxyzABCDEFGHJKLMNOPQRSTUVWXYZ0123456789";
    var randNum = new Random();
    var passwordSalt = new char[saltlength];

    for (var i = 0; i <= saltlength - 1; i++) 
        passwordSalt[i] = chars[Convert.ToInt32((chars.Length) * randNum.NextDouble())];
    
    return new string(passwordSalt);

public static string EncodePassword(string pass, string salt) //encrypt password

    byte[] bytes = Encoding.Unicode.GetBytes(pass);
    byte[] src = Encoding.Unicode.GetBytes(salt);
    byte[] dst = new byte[src.Length + bytes.Length];
    Buffer.BlockCopy(src, 0, dst, 0, src.Length);
    Buffer.BlockCopy(bytes, 0, dst, src.Length, bytes.Length);
    HashAlgorithm algorithm = HashAlgorithm.Create("MD5");
    if (algorithm != null) 
        byte[] inArray = algorithm.ComputeHash(dst);
        var encodedPassword = Convert.ToBase64String(inArray);
        return encodedPassword;
    
    return pass;

关于如何修复此错误的任何建议?

【问题讨论】:

HashAlgorithm.Create 在 .NET Core 上不受支持,请参阅 github.com/dotnet/corefx/wiki/…。我猜你应该直接实例化它,例如通过使用MD5 class。话虽这么说,您不应该在当今时代使用 MD5,因为它已经有好几年不安全了。也不要只是散列你的密码,加盐并使用像 Rfc2898DeriveBytes 类这样的密钥派生函数。 如果你知道你在使用 MD5,为什么不使用MD5.Create() 不要使用 MD5 来散列密码。永远! 谢谢大家帮助我。这是一个特例,我只需要一个临时解决方案。该系统位于安全防火墙后面,并且位于具有单向流量的 Intranet 上。 【参考方案1】:

对于这个问题有一个github issue 提供了一个解决方法:

解决方法是调用 (HashAlgorithm)CryptoConfig.CreateFromName(string),虽然打电话 一般不鼓励直接使用 CryptoConfig。

【讨论】:

【参考方案2】:

要创建 MD5 哈希对象,请使用 MD5.Create()。使用 CryptoConfig 或 HashAlgorithm.Create(String) 的唯一原因是在处理动态需求时。

【讨论】:

【参考方案3】:

正如在其他答案中所指出的,使用 MD5 作为密码的散列算法并不是一个好主意,因为它太容易破解。虽然说 MD5 通常不安全并不完全正确,但它对于密码散列是不安全的。

基本上是一个简单的散列问题,运行一次迭代太便宜了。这就是为什么名为Key Derivation Function 的东西用于此目的的原因。这个想法是您需要一个 CPU 密集型算法(具有多次迭代)来进行散列。虽然它对一个用户来说是非常透明的(比如说 100 毫秒),但破解起来太昂贵了。

.Net 为此内置了Rfc2898DerivedBytes。这不是最容易使用的类,所以我在这个类之上做了一个小库:SimpleHashing.Net。

您可以直接使用它,也可以在需要 .Net Standard 时直接使用代码。还没来得及编译成标准版。

【讨论】:

【参考方案4】:

这个问题似乎在 .NET Core 2.1 中得到修复:HashAlgorithm.Create throws PNSE on .NET Core 2 #22929

所以升级到 2.1(或更高版本)应该可以解决问题。

正如其他答案所示,通常您应该使用MD5.Create(或者实际上更好的算法,例如SHA256.Create)。但在某些情况下,您可能会收到错误,因为您的项目正在使用它的其他程序集调用HashAlgorithm.Create,因此您无法更改它。

【讨论】:

以上是关于HashAlgorithm.Create 在 C# ASP.NET Core 2 中因 PlatformNotSupportedException 而失败的主要内容,如果未能解决你的问题,请参考以下文章

判断两个文件是否相同

用MD5比较两文件是否相等

SHA512 算法的哈希值是 128 位长吗?

在 C# 中以编程方式检查字符串是不是包含有效的 C# 代码

C# - 使用自定义配置在运行时编译 c# 代码

c# 在 c# 应用程序中保存配置数据的最佳方法是啥。 [复制]