【问题标题】:Why do all the variants of SHA256 appear as SHA256Managed?为什么 SHA256 的所有变体都显示为 SHA256Managed?
【发布时间】:2013-12-07 05:08:42
【问题描述】:

我正在编写一个扩展方法,通过删除大量样板来简化哈希的创建,但是我的问题是,每当我单步执行代码时,我都可以看到它总是选择@ 987654321@,不管我打给SHA256.Create()SHA256Cng.Create()SHA256Managed.Create()还是SHA256CryptoServiceProvider.Create()

当我选择不同的哈希算法(如 MD5)时,情况相同,但在 MD5 的情况下,它总是选择MD5CryptoServiceProvider,而不管我实际使用的类...

这是为什么呢?

这是我的代码:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Security.Cryptography;
using System.Text;
using System.Threading.Tasks;

namespace Utility.Methods
{
    public enum HashType { MD5, SHA512, SHA256, SHA384, SHA1 }
    public enum HashSubType {Normal, Cng, Managed, CryptoServiceProvider}

    public static class TextHasher
    {
        public static string Hash(this string input, HashType hash, HashSubType subType = HashSubType.Normal)
        {
            Func<HashAlgorithm, string> hashFunction = alg => HashingHelper(input, alg);

            switch (subType)
            {
                case HashSubType.Normal:
                    return hashFunction(NormalHashes(hash));
                case HashSubType.Cng:
                    return hashFunction(CngHashes(hash));
                case HashSubType.Managed:
                    return hashFunction(ManagedHashes(hash));
                case HashSubType.CryptoServiceProvider:
                    return hashFunction(CSPHashes(hash));
                default: return "error"; // unreachable
            }
        }

        private static string HashingHelper(string text, HashAlgorithm algorithm)
        {
            Func<string, byte[]> getHash = input => algorithm.ComputeHash(Encoding.UTF8.GetBytes(input));

            var sb = new StringBuilder();
            Array.ForEach(getHash(text), b => sb.Append(b.ToString("X")));

            return sb.ToString();
        }

        private static HashAlgorithm NormalHashes(HashType hash)
        {
            switch (hash)
            {
                case HashType.MD5:
                    return MD5.Create();
                case HashType.SHA1:
                    return SHA1.Create();
                case HashType.SHA256:
                    return SHA256.Create();
                case HashType.SHA384:
                    return SHA384.Create();
                case HashType.SHA512:
                    return SHA512.Create();
                default: return null; // unreachable
            }
        }

        private static HashAlgorithm CngHashes(HashType hash)
        {
            switch (hash)
            {
                case HashType.MD5:
                    return MD5Cng.Create();
                case HashType.SHA1:
                    return SHA1Cng.Create();
                case HashType.SHA256:
                    return SHA256Cng.Create();
                case HashType.SHA384:
                    return SHA384Cng.Create();
                case HashType.SHA512:
                    return SHA512Cng.Create();
                default: return null; // unreachable
            }
        }

        private static HashAlgorithm ManagedHashes(HashType hash)
        {
            switch (hash)
            {
                case HashType.SHA1:
                    return SHA1Managed.Create();
                case HashType.SHA256:
                    return SHA256Managed.Create();
                case HashType.SHA384:
                    return SHA384Managed.Create();
                case HashType.SHA512:
                    return SHA512Managed.Create();
                default: return null; // unreachable
            }
        }

        private static HashAlgorithm CSPHashes(HashType hash)
        {
            switch (hash)
            {
                case HashType.MD5:
                    return MD5CryptoServiceProvider.Create();
                case HashType.SHA1:
                    return SHA1CryptoServiceProvider.Create();
                case HashType.SHA256:
                    return SHA256CryptoServiceProvider.Create();
                case HashType.SHA384:
                    return SHA384CryptoServiceProvider.Create();
                case HashType.SHA512:
                    return SHA512CryptoServiceProvider.Create();
                default: return null; // unreachable
            }
        }
    }
}

那么,有什么帮助吗?

【问题讨论】:

  • 这并不特别令人惊讶(但我认为它应该会生成警告),因为 Create 是在 SHA256 类上静态定义的,并且其他类继承自该类,所以你'在每种情况下都调用相同的方法。非抽象类有公共构造函数。
  • 那么如果 create 方法没有改变它正在做的事情,那么拥有其他版本的类有什么意义呢?
  • 因为这些类的实例做不同的事情。它们只是与您的用例无关。
  • 1) 你可以直接construct 其他版本的类,如果你想获得的话,2) 你可以使用Create 的重载,它接受一个字符串来选择一个非默认值,以及 3) 如果您使用此重载,要构造的类是在机器级别配置的,而不是硬编码的。
  • 如果文档没有指定使用哪些字符串是合法的,那将不是很有帮助...我基本上可以这样做SHA256.Create("Dog");

标签: c# hash md5 checksum sha256


【解决方案1】:

那是因为你总是调用同一个静态方法,SHA256.Create。 SHA256 是一个抽象类,它的后代提供替代方法。事实上,Resharper 会警告您正在从派生类型访问静态成员。

其实调用 SHA256.Create 和调用HashAlgorithm.Create 是一样的。两个类在内部调用相同的实现,并简单地将结果转换为不同的类型。

SHA256.Create 方法将创建在 machine.config 中指定的默认实现,并且可以在您的 app.config 中覆盖

如果您想使用特定的提供者,请使用SHA256.Create(string) 传递您要使用的提供者的名称。

例如:

SHA256.Create("System.Security.Cryptography.SHA256Cng");
HashAlgorithm.Create("System.Security.Cryptography.SHA256Cng");
SHA256.Create("System.Security.Cryptography.SHA256CryptoServiceProvider");

编辑

HashAlgorithm.Create 的文档指定了有效算法名称的列表。 MSDN 文章 Mapping Algorithm Names to Cryptography Classes 描述了如何将算法名称映射到其他提供程序(您自己的、第三方的、硬件加速的或其他)并使用它们而不是默认算法。

编辑 2

也可以通过编程方式更改映射。因此,要将“Dog”映射到 SHA512CryptoServiceProvider,您只需编写:

CryptoConfig.AddAlgorithm(
             typeof(System.Security.Cryptography.SHA512CryptoServiceProvider),
             "Dog");
var t4 = HashAlgorithm.Create("Dog");

【讨论】:

  • 但我不是每次都使用 sha256.create ......我使用 sha256Managed.create 和 sha256Cng.create 为其他人,它仍然给我同样的结果......
  • @ElectricCoffee - 没有 sha256Managed.Create 方法 - 但 sha256Managed inherits 来自 Sha256,因此可以编译调用。
  • 重点是什么?您以错误的方式调用静态方法。如果要创建不同的实现,只需使用带有提供者名称的 Create(string)
  • 是的,谢谢,如果我知道字符串应该包含什么内容会有所帮助,因为文档没有告诉我这个...你知道吗?我要做一个SHA256.Create("Dog");
  • 只使用类型名称。我添加了一些例子
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-09-28
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多