Why are all SHA256 options displayed as SHA256Managed?

I am writing an extension method that makes it easy to create hashes by removing the thinness of the template, my problem is that whenever I look at the code, I see that it always selects SHA256Managed , regardless of whether I SHA256.Create() , SHA256Cng.Create() , SHA256Managed.Create() or SHA256CryptoServiceProvider.Create()

This is the same story when I choose a different hashing algorithm like MD5, but in the case of MD5, it always selects MD5CryptoServiceProvider regardless of the class that I actually use ...

Why is this?

Here is my code:

 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 } } } } 

So any help?

+6
source share
1 answer

This is because you always invoke the same static method, SHA256.Create . SHA256 is an abstract class, and its descendants do not provide an alternative method. In fact, Resharper will give you a warning that you are accessing a static member from a derived type.

Actually, calling SHA256.Create is similar to calling HashAlgorithm.Create . Both classes use the same implementation within themselves and simply cast the result to different types.

The SHA256.Create method will create the default implementation specified in the machine.config file and can be overridden in your app.config

If you want to use a specific provider, use SHA256.Create (string) , passing in the name of the provider you want to use.

Examples:

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

EDIT

The HashAlgorithm.Create documentation indicates a list of valid algorithm names. The MSDN article, Cryptography Class Mapping Algorithm Names , describes how you can map the algorithm names to other providers (your own, third-party, hardware accelerations, or something else) and use them instead of the default algorithms.

EDIT 2

It is also possible to programmatically change the display. So, to map Dog to SHA512CryptoServiceProvider, you just need to write:

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

Source: https://habr.com/ru/post/958632/


All Articles