I am using the method below to sign Xml Documents:
public static XmlDocument SignDocument(XmlDocument doc)
{
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 = "#_73e63a41-156d-4fda-a26c-8d79dcade713";
CryptoConfig.AddAlgorithm(typeof(RSAPKCS1SHA256SignatureDescription), signatureMethod);
var signingCertificate = GetCertificate();
SignedXml signer = new SignedXml(doc);
signer.SigningKey = signingCertificate.PrivateKey;
signer.KeyInfo = new KeyInfo();
signer.KeyInfo.AddClause(new KeyInfoX509Data(signingCertificate));
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();
doc.DocumentElement.AppendChild(signer.GetXml());
return doc;
}
private static X509Certificate2 GetCertificate()
{
X509Store store = new X509Store(StoreName.My, StoreLocation.LocalMachine);
store.Open(OpenFlags.ReadOnly);
X509Certificate2 card = null;
foreach (X509Certificate2 cert in store.Certificates)
{
if (!cert.HasPrivateKey) continue;
if (cert.Thumbprint.Equals("a_certain_thumb_print", StringComparison.OrdinalIgnoreCase))
{
card = cert;
break;
}
}
store.Close();
return card;
}
An exception of type System.Security.Cryptography.CryptographicException is thrown when trying to compute the signature with the error message Invalid algorithm specified. Any ideas?
Machine: Windows Server 2008 R2
.Net Framework: 4.0.
IDE: Visual Studio 2010.
An XML digital signature (XML DSIG) is an electronic, encrypted, stamp of authentication on digital information such as messages. The digital signature confirms that the information originated from the signer and was not altered in transmission.
There are three types of XML Digital Signatures. The Classification of the type depends on the position of the signature in relation to the data being signed. The three types are Detached, Enveloping and Enveloped signature. The following sections describe of each of these three types of XML Digital Signature.
XML Signatures can be applied to data of any type, XML or binary (see XML Signature Syntax and Processing). The resulting signature is represented in XML. An XML Signature can be used to secure your data and provide data integrity, message authentication, and signer authentication.
Thanks so much for this blog. It actually solved my problem. By the way, if certificate is loaded from file, it should be exportable: X509Certificate2 x509Key = new X509Certificate2("xxxxx.pfx", "123", X509KeyStorageFlags.Exportable);
string signatureMethod = @"http://www.w3.org/2001/04/xmldsig-more#rsa-sha256";
This signature method is not implemented in .NET according to https://msdn.microsoft.com/en-us/library/system.security.cryptography.xml.signedinfo.signaturemethod(v=vs.110).aspx
The reply from @minhj mentions about some blog, but the link is not there.
However, adding the class mentioned here and registering it fixed the problem. Seems it should be registered only once per app domain.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With