Every time I try to send a signed XML, the web service verifier rejects it.
To sign the document I just adapted this sample code provided by Microsoft:
http://msdn.microsoft.com/es-es/library/ms229745(v=vs.110).aspx
My implementation:
public static XmlDocument FirmarXML(XmlDocument xmlDoc)
{
try
{
X509Certificate2 myCert = null;
var store = new X509Store(StoreLocation.CurrentUser); //StoreLocation.LocalMachine fails too
store.Open(OpenFlags.ReadOnly);
var certificates = store.Certificates;
foreach (var certificate in certificates)
{
if (certificate.Subject.Contains("xxx"))
{
myCert = certificate;
break;
}
}
if (myCert != null)
{
RSA rsaKey = ((RSA)myCert.PrivateKey);
// Sign the XML document.
SignXml(xmlDoc, rsaKey);
}
}
catch (Exception e)
{
MessageBox.Show(e.Message);
}
return xmlDoc;
}
// Sign an XML file.
// This document cannot be verified unless the verifying
// code has the key with which it was signed.
public static void SignXml(XmlDocument xmlDoc, RSA Key)
{
// Check arguments.
if (xmlDoc == null)
throw new ArgumentException("xmlDoc");
if (Key == null)
throw new ArgumentException("Key");
// Create a SignedXml object.
SignedXml signedXml = new SignedXml(xmlDoc);
// Add the key to the SignedXml document.
signedXml.SigningKey = Key;
// Create a reference to be signed.
Reference reference = new Reference();
reference.Uri = "";
// Add an enveloped transformation to the reference.
XmlDsigEnvelopedSignatureTransform env = new XmlDsigEnvelopedSignatureTransform();
reference.AddTransform(env);
// Add the reference to the SignedXml object.
signedXml.AddReference(reference);
// 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.DocumentElement.AppendChild(xmlDoc.ImportNode(xmlDigitalSignature, true));
}
I think I am following the same steps using my own certificate, however it doesn't works as expected.
Any suggestion will be welcome.
How does the server know what certificate the document is signed with? You seem to not to include the cert in the signed document:
If you need more details, consult my blog entry
http://www.wiktorzychla.com/2012/12/interoperable-xml-digital-signatures-c_20.html
I already made some changes following the Wiktor's samples. However the signature still rejected by the web service.
The method I use to sign now is this:
And the signature appears like this in the document:
When a right document is sent to the server, this returns this signature that I used as a patter to identify the necessary fields:
It seems to me right. However still not work. Any one has any clue?