Hello,
I am trying to use C# and SignedXml to sign (and verify) some external data like this:
static string flXML = @"C:\Temp\Example.xml"; static string flSignedXML = @"C:\Temp\SignedExample.xml"; static void Main(string[] args) { try { CryptoConfig.AddAlgorithm(typeof(RSAPKCS1SHA256SignatureDescription), "http://www.w3.org/2001/04/xmldsig-more#rsa-sha256"); // Generate a signing key. RSACryptoServiceProvider Key = new RSACryptoServiceProvider(); SignXmlFile(flXML, flSignedXML, Key); bool result = VerifyXmlFile(flSignedXML, Key); if (result) Console.WriteLine("The XML signature is valid."); else Console.WriteLine("The XML signature is not valid."); } catch (CryptographicException e) { Console.WriteLine(e.Message); } } public static void SignXmlFile(string FileName, string SignedFileName, RSA Key) { XmlDocument doc = new XmlDocument(); doc.Load(new XmlTextReader(FileName)); SignedXml signedXml = new SignedXml(doc); signedXml.SigningKey = Key; signedXml.SignedInfo.SignatureMethod = "http://www.w3.org/2001/04/xmldsig-more#rsa-sha256"; // Create a reference to be signed. Reference reference = new Reference(); reference.Uri = ""; reference.AddTransform(new XmlDsigEnvelopedSignatureTransform()); reference.AddTransform(new XmlDsigExcC14NTransform()); reference.DigestMethod = "http://www.w3.org/2001/04/xmlenc#sha256"; signedXml.AddReference(reference); // Add the extgernal data to be signed to the SignedXml object. { byte[] Content = System.Text.Encoding.UTF8.GetBytes("12345qwert67890asdfg"); Stream stream = new MemoryStream(Content); Reference reference2 = new Reference(stream); reference2.Uri = "cid:xml-sample"; reference2.DigestMethod = "http://www.w3.org/2001/04/xmlenc#sha256"; signedXml.AddReference(reference2); } signedXml.ComputeSignature(); XmlElement xmlDigitalSignature = signedXml.GetXml(); doc.DocumentElement.AppendChild(doc.ImportNode(xmlDigitalSignature, true)); if (doc.FirstChild is XmlDeclaration) { doc.RemoveChild(doc.FirstChild); } XmlTextWriter xmltw = new XmlTextWriter(SignedFileName, new UTF8Encoding(false)); doc.WriteTo(xmltw); xmltw.Close(); } public static Boolean VerifyXmlFile(String Name, RSA Key) { XmlDocument xmlDocument = new XmlDocument(); xmlDocument.Load(Name); SignedXml signedXml = new SignedXml(xmlDocument); XmlNodeList nodeList = xmlDocument.GetElementsByTagName("Signature"); signedXml.LoadXml((XmlElement)nodeList[0]); { byte[] Content = System.Text.Encoding.UTF8.GetBytes("12345qwert67890asdfg"); Stream stream = new MemoryStream(Content); Reference reference2 = new Reference(stream); reference2.Uri = "cid:xml-sample"; reference2.DigestMethod = "http://www.w3.org/2001/04/xmlenc#sha256"; signedXml.AddReference(reference2); } signedXml.SigningKey = Key; // Check the signature and return the result. return signedXml.CheckSignature(); }
and CheckSignature always returns false!
Input XML:
<MyElement xmlns="samples"><PayloadInfo><PartInfo href="cid:xml-sample"> </PartInfo></PayloadInfo></MyElement>
Signed XML looks OK to me:
<MyElement xmlns="samples"><PayloadInfo><PartInfo href="cid:xml-sample"></PartInfo></PayloadInfo><Signature xmlns="http://www.w3.org/2000/09/xmldsig#"><SignedInfo><CanonicalizationMethod Algorithm="http://www.w3.org/TR/2001/REC-xml-c14n-20010315" /><SignatureMethod Algorithm="http://www.w3.org/2001/04/xmldsig-more#rsa-sha256" /><Reference URI=""><Transforms><Transform Algorithm="http://www.w3.org/2000/09/xmldsig#enveloped-signature" /><Transform Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#" /></Transforms><DigestMethod Algorithm="http://www.w3.org/2001/04/xmlenc#sha256" /><DigestValue>pfmPOwgPEutZr/DP1U3KoBO/7dHnq0PlJm+f0Cx0HLE=</DigestValue></Reference><Reference URI="cid:xml-sample"><DigestMethod Algorithm="http://www.w3.org/2001/04/xmlenc#sha256" /><DigestValue>2QmqZagw72ea4w4UXVhSt5I0AJ7lcUx5rRsvQMVnz4g=</DigestValue></Reference></SignedInfo><SignatureValue>Y/cHki0vVO2CNLHdSaGsTRVueSH/OsYmCspLByKnlcK8XM7kjcFiSuocxz8xsUVv3bk8LtgRMtDK3eZQr8WmKSBDkgEWmVF88xAArDPm0DJVZn89RX6rAIvcitnDXG/oAOwTxyW9wQoKzWqg3fyrCq4o0g2J0zr8vcPmQVrgdJg=</SignatureValue></Signature></MyElement>
Beautified:
<MyElement xmlns="samples"><PayloadInfo><PartInfo href="cid:xml-sample"></PartInfo></PayloadInfo><Signature xmlns="http://www.w3.org/2000/09/xmldsig#"><SignedInfo><CanonicalizationMethod Algorithm="http://www.w3.org/TR/2001/REC-xml-c14n-20010315" /><SignatureMethod Algorithm="http://www.w3.org/2001/04/xmldsig-more#rsa-sha256" /><Reference URI=""><Transforms><Transform Algorithm="http://www.w3.org/2000/09/xmldsig#enveloped-signature" /><Transform Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#" /></Transforms><DigestMethod Algorithm="http://www.w3.org/2001/04/xmlenc#sha256" /><DigestValue>pfmPOwgPEutZr/DP1U3KoBO/7dHnq0PlJm+f0Cx0HLE=</DigestValue></Reference><Reference URI="cid:xml-sample"><DigestMethod Algorithm="http://www.w3.org/2001/04/xmlenc#sha256" /><DigestValue>2QmqZagw72ea4w4UXVhSt5I0AJ7lcUx5rRsvQMVnz4g=</DigestValue></Reference></SignedInfo><SignatureValue>Y/cHki0vVO2CNLHdSaGsTRVueSH/OsYmCspLByKnlcK8XM7kjcFiSuocxz8xsUVv3bk8LtgRMtDK3eZQr8WmKSBDkgEWmVF88xAArDPm0DJVZn89RX6rAIvcitnDXG/oAOwTxyW9wQoKzWqg3fyrCq4o0g2J0zr8vcPmQVrgdJg=</SignatureValue></Signature></MyElement>
If I do not include second Reference (external data) CheckSignature will return true.
Does anyone knows what I am doing wrong ?
Thanks,
Sasa Kajic