SHA256 signing stops working in .NET 4.5
While this question was asked almost a year ago, it has received some up votes recently which may indicate that some other people are getting the same problem. Hopefully this answer can help :) Briefly speaking, the error doesn't happen in all machines but only in some of them. I guess it depends on what CSPs have been registered on a specific machine. Anyway, in my specific case, the certificate was generated with either "Microsoft RSA SChannel..." or "Microsoft strong cryptographic provider" as the CSP. I generated a new certificate but used "Microsoft Enhanced RSA and AES Cryptographic Provider" as the CSP and it SHA256 signing started working for me.
Some references:
https://social.msdn.microsoft.com/Forums/vstudio/en-US/e391ba75-ce6e-431c-bfc9-26a71ae1b033/sha256-signing-stops-working-in-net-45?forum=Geneva (as you can see, million thanks to Paul who helped me solve this issue)
http://hintdesk.com/c-how-to-fix-invalid-algorithm-specified-when-signing-with-sha256/
Had the same problem with XmlDsig (trying to make enveloping signature of xml document with RSA-SHA256 algorithm). First I were getting exception
System.Security.Cryptography.CryptographicException: SignatureDescription could not be created for the signature algorithm supplied.
Then I found mention of RSAPKCS1SHA256SignatureDescription
- signature description implementation for RSA-SHA256 signatures.
Full implementation here:
http://clrsecurity.codeplex.com/SourceControl/changeset/view/47833#269110
or here: https://gist.github.com/sneal/f35de432115b840c4c1f
You have to manually call once per appdomain:
CryptoConfig.AddAlgorithm(typeof(RSAPKCS1SHA256SignatureDescription), "http://www.w3.org/2001/04/xmldsig-more#rsa-sha256");
After that I got a new exception:
System.Security.Cryptography.CryptographicException: Invalid algorithm specified.
This brought me to your question. After reading suggested article I have made a new key and certificate (with OpenSSL) using Microsoft Enhanced RSA and AES Cryptographic Provider
.
To my surprise, this new certificate allowed me to successfully make a signature.
After some more investigation I have found interesting answer of Andrew here https://stackoverflow.com/a/17285774/328785, where he used RSACryptoServiceProvider
to prepare SecretKey for SignedXml
class.
Specifically this part (my interpretation):
var store = new X509Store(StoreName.My, StoreLocation.CurrentUser);
store.Open(OpenFlags.OpenExistingOnly | OpenFlags.ReadOnly);
var certificates = store.Certificates.Find(X509FindType.FindBySerialNumber, "54dba096", true);
var certificate = certificates[0];
// next three lines
var cspParams = new CspParameters(24) { KeyContainerName = "XML_DSIG_RSA_KEY" };
var key = new RSACryptoServiceProvider(cspParams);
key.FromXmlString(certificate.PrivateKey.ToXmlString(true));
SignedXml sxml = new SignedXml(doc);
sxml.SigningKey = key;
And this solutions worked fine even with old key!