Runtime: Cryptography types unsealed in netstandard2.0

Created on 30 May 2020  路  8Comments  路  Source: dotnet/runtime

These classes are marked as sealed (static) in netstandard2.0 :

System.Security.Cryptography.SHA1Managed
System.Security.Cryptography.SHA256Managed
System.Security.Cryptography.SHA384Managed
System.Security.Cryptography.SHA512Managed

we can麓t inherit so we can麓t use HashCore nor HashFinal.
The implementation is just a wrapper/proxy of HashProvider but HashProvider is an internal class.
I can understand you don麓t want us to use it but we need some alternative for some scenario where performances and memory usage are an issue. In my case I have to "manipulate" large streams during the hash calculation and to do it I need to use HashCore and HashFinal.
Is there a chance to remove the sealed just to the class?

related issue: https://github.com/dotnet/runtime/issues/20870

api-suggestion area-System.Security untriaged

Most helpful comment

The issue with nonpublic HashSize was replaced by constants.

For what it's worth, in .NET 5 there will be HashSizeInBytes on IncrementalHash which is being introduced in #37936. So you would be able to do ih.HashSizeInBytes * 8 to get the bit size.

All 8 comments

Tagging subscribers to this area: @bartonjs, @vcsjones, @krwq
Notify danmosemsft if you want to be subscribed.

Would IncrementalHash work better for your performance sensitive scenario? It's mostly just a thin wrapper around HashProvider.

I'm open to know which is the current alternative to create a method with an implementation similar to HashAlgorithm.ComputeHash(Stream inputStream) using netstandard2.0.

Well, you could read from a stream and use AppendData from your stream buffer using IncrementalHash. Once you are done appending your data, use GetHashAndReset to finalize the digest.

Something like this:

using System;
using System.IO;
using System.Security.Cryptography;

static class Hasher {
    public static byte[] HashStream(Stream stream, HashAlgorithmName alg) {
        using (IncrementalHash hash = IncrementalHash.CreateHash(alg)) {
            byte[] buffer = new byte[4096];
            int bytesRead;

            while ((bytesRead = stream.Read(buffer, 0, buffer.Length)) > 0)
            {
                hash.AppendData(buffer, 0, bytesRead);
            }

            Array.Clear(buffer, 0, buffer.Length);
            return hash.GetHashAndReset();
        }
    }
}

That should work for hashing a stream, and you could tweak this with the changes that you mentioned.

@vcsjones let me check if everything is there with public access.

IncrementalHash does not expose the HashSize. Even using composition instead of inheritance I麓m having some problem... BDW perhaps I can put a static know value ;)
I麓ll try everything in a few hours.

OK everything working; all green.
The issue with nonpublic HashSize was replaced by constants.
@vcsjones thanks for the advice.

The issue with nonpublic HashSize was replaced by constants.

For what it's worth, in .NET 5 there will be HashSizeInBytes on IncrementalHash which is being introduced in #37936. So you would be able to do ih.HashSizeInBytes * 8 to get the bit size.

Was this page helpful?
0 / 5 - 0 ratings