I am trying to implement XML signing with dot net 4.5 on windows server using sha 256 certificates . And I am getting - $exception "Invalid algorithm specified." . After googling I found that my NAP client has request policy as "Microsoft RSA Channel Cryptography Provider" and hash algorithm as SHA1RSA. Can I do any change in my code or use any other dlls to solve this issue?
public class RSAPKCS1SHA256SignatureDescription :SignatureDescription
{
/// <summary>
/// Registers the http://www.w3.org/2001/04/xmldsig-more#rsa-sha256 algorithm
/// with the .NET CrytoConfig registry. This needs to be called once per
/// appdomain before attempting to validate SHA256 signatures.
/// </summary>
public static void Register()
{
CryptoConfig.AddAlgorithm(
typeof(RSAPKCS1SHA256SignatureDescription),
"http://www.w3.org/2001/04/xmldsig-more#rsa-sha256");
}
/// <summary>
/// .NET calls this parameterless
/// </summary>
public RSAPKCS1SHA256SignatureDescription()
{
KeyAlgorithm = "System.Security.Cryptography.RSACryptoServiceProvider";
DigestAlgorithm = "System.Security.Cryptography.SHA256Managed";
FormatterAlgorithm = "System.Security.Cryptography.RSAPKCS1SignatureFormatter";
DeformatterAlgorithm = "System.Security.Cryptography.RSAPKCS1SignatureDeformatter";
}
public override AsymmetricSignatureDeformatter CreateDeformatter(AsymmetricAlgorithm key)
![enter image description here][1] {
var asymmetricSignatureDeformatter =
(AsymmetricSignatureDeformatter)CryptoConfig.CreateFromName(DeformatterAlgorithm);
asymmetricSignatureDeformatter.SetKey(key);
asymmetricSignatureDeformatter.SetHashAlgorithm("SHA256");
return asymmetricSignatureDeformatter;
}
public override AsymmetricSignatureFormatter CreateFormatter(AsymmetricAlgorithm key)
{
var asymmetricSignatureFormatter =
(AsymmetricSignatureFormatter)CryptoConfig.CreateFromName(FormatterAlgorithm);
asymmetricSignatureFormatter.SetKey(key);
asymmetricSignatureFormatter.SetHashAlgorithm("SHA256");
return asymmetricSignatureFormatter;
}
}
public String signExchangeRPmetadata(X509Certificate2 exchangeCerti)
{
string signatureCanonicalizationMethod = "http://www.w3.org/2001/10/xml-exc-c14n#";
string signatureMethod = @"http://www.w3.org/2001/04/xmldsig-more#rsa-sha256";
string digestMethod = @"http://www.w3.org/2001/04/xmlenc#sha256";
string signatureReferenceURI = " ";
//For .NET 4.5 and above, SHA-256 support is, for the most part, built into the .NET framework. The only requirement is to register the cryptographic algorithm
CryptoConfig.AddAlgorithm(typeof(RsaPkCs1Sha256SignatureDescription), signatureMethod);
//CryptoConfig.AddAlgorithm(typeof(RSAPKCS1SHA256SignatureDescription),"http://www.w3.org/2001/04/xmldsig-more#rsa-sha256");
String path = "C:\\\\certificate\\certificate\\sha-256\\Exchange_RP.xml";
XmlDocument exchangeAsRPXML = new XmlDocument();
exchangeAsRPXML.Load(path);
XmlNamespaceManager nameSpaceMgr = new XmlNamespaceManager(exchangeAsRPXML.NameTable);
nameSpaceMgr.AddNamespace("ab", "urn:oasis:names:tc:SAML:2.0:metadata");
CspParameters cspParams = new CspParameters(24); cspParams.KeyContainerName = "XML_DISG_RSA_KEY";
RSACryptoServiceProvider key = new RSACryptoServiceProvider(cspParams);
key.FromXmlString(exchangeCerti.PrivateKey.ToXmlString(true));
SignedXml signer = new SignedXml(exchangeAsRPXML);
signer.SigningKey = exchangeCerti.PrivateKey;
signer.KeyInfo = new KeyInfo();
signer.KeyInfo.AddClause(new KeyInfoX509Data(exchangeCerti));
signer.SignedInfo.CanonicalizationMethod = signatureCanonicalizationMethod;
signer.SignedInfo.SignatureMethod = signatureMethod;
XmlDsigEnvelopedSignatureTransform envelopeTransform = new XmlDsigEnvelopedSignatureTransform();
XmlDsigExcC14NTransform cn14Transform = new XmlDsigExcC14NTransform();
Reference signatureReference = new Reference();
signatureReference.Uri = signatureReferenceURI;
signatureReference.AddTransform(envelopeTransform);
signatureReference.AddTransform(cn14Transform);
signatureReference.DigestMethod = digestMethod;
signer.AddReference(signatureReference);
signer.ComputeSignature();
XmlElement signatureElement = signer.GetXml();
exchangeAsRPXML.DocumentElement.AppendChild(signer.GetXml());
return null;
}
Exception :
at System.Security.Cryptography.CryptographicException.ThrowCryptographicException(Int32 hr)\r\n at System.Security.Cryptography.Utils.SignValue(SafeKeyHandle hKey, Int32 keyNumber, Int32 calgKey, Int32 calgHash, Byte[] hash, Int32 cbHash, ObjectHandleOnStack retSignature)\r\n at System.Security.Cryptography.Utils.SignValue(SafeKeyHandle hKey, Int32 keyNumber, Int32 calgKey, Int32 calgHash, Byte[] hash)\r\n at System.Security.Cryptography.RSACryptoServiceProvider.SignHash(Byte[] rgbHash, Int32 calgHash)\r\n at System.Security.Cryptography.RSAPKCS1SignatureFormatter.CreateSignature(Byte[] rgbHash)\r\n at System.Security.Cryptography.AsymmetricSignatureFormatter.CreateSignature(HashAlgorithm hash)\r\n at System.Security.Cryptography.Xml.SignedXml.ComputeSignature()\r\n at ContactManager.Controllers.ProductController.signExchangeRPmetadata(X509Certificate2 exchangeCerti)
References: Followed this stackoverflow thread