1

I am trying to sign a stream using the method below but I always get a Cryptographic Exception saying that it is not a valid hash algorithm even though it is listed in the documentation:

byte[] SignData(RSACryptoServiceProvider rsa, Stream stream, string hashName)
{
    HashAlgorithm hash = HashAlgorithm.Create(hashName);
    byte[] signature = rsa.SignData(stream, hash);
    return signature;
}

I am calling it with "SHA256" as the hashName parameter. and the exception is thrown at the line where rsa.SignData() is called.

This is NOT using X509 certificates, it is not a duplicate. BTW see answer below.

Lord of Scripts
  • 3,579
  • 5
  • 41
  • 62
  • 1
    FYI, there is also [Information Security](https://security.stackexchange.com/) for these kinds of questions. – 500 - Internal Server Error Jul 24 '17 at 22:09
  • Possible duplicate of [Why am I getting "Invalid algorithm specified" exception](https://stackoverflow.com/questions/7433074/why-am-i-getting-invalid-algorithm-specified-exception) – anothermh Jul 24 '17 at 22:09

2 Answers2

2

Just resolved and it is not a duplicate because I am using the plain RSACryptoServiceProvider of .NET and not X509 certificates.

I ran into this post: http://hintdesk.com/c-how-to-fix-invalid-algorithm-specified-when-signing-with-sha256/

Reading it it occurred to me to to examine the RSA SignatureAlgorithm and it the resulting URI indicated it was SHA1 so no SHA256 or SHA512. Then I looked up that property in MSDN documentation and it says that property always returns that value because it only supports that, so only SHA1.

Lord of Scripts
  • 3,579
  • 5
  • 41
  • 62
2

Software-backed RSACryptoServiceProvider is only capable of doing RSA signature using a SHA-2 digest algorithm when the CSP ProviderType value is 24 (PROV_RSA_AES) and the ProviderName is "Microsoft Enhanced RSA and AES Cryptographic Provider" (MS_ENH_RSA_AES_PROV). Hardware may or may not require PROV_RSA_AES, just depends on the hardware.

RSACng can always do RSA signature using a SHA-2 digest (unless hardware backed and the hardware refuses to, but that seems unlikely), and RSACng is also capable of doing RSA OAEP encryption using a SHA-2 digest (RSACryptoServiceProvider only has PKCS#1 v1.5 and OAEP-SHA-1), and RSA PSS signature.

But RSACryptoServiceProvider was the only builtin RSA provider for so long that it took until .NET Framework 4.6.2 to get the whole of the framework happy with accepting RSACng (added in 4.6).

As for the SignatureAlgorithm property, it's hard-coded to be the SHA-1 XML value. You can't extract any information from it. (https://referencesource.microsoft.com/#mscorlib/system/security/cryptography/rsacryptoserviceprovider.cs,e4a5c015070c0714)

bartonjs
  • 30,352
  • 2
  • 71
  • 111