I'm currently trying to sign an xml document using a provided p12 file, and I've managed to sign it I suppose, but after sending the document via SOAP, the response I always get is "Invalid Signature". The result xml itself has the same arhitecture as the one provided in the operators example - therefore the only thing that could be faulty is my signature value. What bothers me most is that setting the SignatureMethod and DigestMethod in my code is based purely on placing a couple of URI values - therefore my question is - am I doing it right (since I have to use SHA1, not the default SHA256)?. The method used for signing the XML :
P.S. The uidCert param creation is as follows : X509Certificate2 uidCert = new X509Certificate2("file.p12", "pass");
public static XDocument SignXml(XmlDocument xmlDoc, X509Certificate2 uidCert)
{
RSA rsaKey = (RSA)uidCert.PrivateKey;
// Check arguments.
if (xmlDoc == null)
throw new ArgumentException("xmlDoc");
if (rsaKey == null)
throw new ArgumentException("Key");
// Create a SignedXml object.
SignedXml signedXml = new SignedXml(xmlDoc);
// Add the key to the SignedXml document.
signedXml.SigningKey = rsaKey;
signedXml.SignedInfo.SignatureMethod = SignedXml.XmlDsigRSASHA1Url;
// Specify a canonicalization method.
signedXml.SignedInfo.CanonicalizationMethod = SignedXml.XmlDsigExcC14NTransformUrl;
// Create a reference to be signed.
Reference reference = new Reference();
reference.Uri = "#billId";
reference.DigestMethod = "http://www.w3.org/2000/09/xmldsig#sha1";
// Add an enveloped transformation to the reference.
XmlDsigEnvelopedSignatureTransform env = new XmlDsigEnvelopedSignatureTransform();
reference.AddTransform(env);
reference.AddTransform(new XmlDsigExcC14NTransform());
// Add the reference to the SignedXml object.
signedXml.AddReference(reference);
// Add an RSAKeyValue KeyInfo (optional; helps recipient find key to validate).
KeyInfo keyInfo = new KeyInfo();
KeyInfoX509Data clause = new KeyInfoX509Data();
clause.AddCertificate(uidCert);
clause.AddIssuerSerial(uidCert.IssuerName.Name, uidCert.SerialNumber);
keyInfo.AddClause(clause);
signedXml.KeyInfo = keyInfo;
// Compute the signature.
signedXml.ComputeSignature();
// Get the XML representation of the signature and save
// it to an XmlElement object.
XmlElement xmlDigitalSignature = signedXml.GetXml();
// Append the element to the XML document.
xmlDoc.GetElementsByTagName("tns:BillRequest").Item(0).AppendChild(xmlDoc.ImportNode(xmlDigitalSignature, true));
return ToXDocument(xmlDoc);
}
Any assistance is greatly appreciated, since I'm not really an expert neither on XML nor digital signatures. And oh by the way, on the side note - How could one place the X509IssuerSerial tag after the X509Certificate tag on the signature???