Domanda

I am trying to sign a XML document using a Digital Signature. I have the certificate installed and the output seems to resemble the specification (EXCEPT the Namespace, which it seems is something I am not able to touch in .NET), however I am unable to get the WebService I am sending this to accept this, and it returns with the Error:

VerifyXml: Verification failed: Signature is not valid

I am NOT in control of this WebService and the supplier of this service claims that other people have no problem with this WebService.

I have also tried using this verification tool:

http://www.aleksey.com/xmlsec/xmldsig-verifier.html

Which returns with the error: data do not match:signature do not match, ergo, I think I am doing something wrong.

My code looks like this:

X509Store store = new X509Store(StoreName.My);
store.Open(OpenFlags.ReadOnly);
X509Certificate2 cert = store.Certificates.Find(X509FindType.FindByThumbprint, "xxxxxx",
    true).OfType<X509Certificate2>().FirstOrDefault();
store.Close();

XmlDocument xmlDoc = new XmlDocument();
XmlNamespaceManager namespaces = new XmlNamespaceManager(xmlDoc.NameTable);
namespaces.AddNamespace("ns", "xxxx");

xmlDoc.PreserveWhitespace = false;
xmlDoc.Load(new XmlTextReader("C:\\Development\\testheader.xml"));

SignedXml signedXml = new SignedXml(xmlDoc);
signedXml.SigningKey = cert.PrivateKey;

Reference reference = new Reference();
reference.Uri = "";

XmlDsigEnvelopedSignatureTransform env = new XmlDsigEnvelopedSignatureTransform();
reference.AddTransform(env);

XmlDsigC14NTransform c14n = new XmlDsigC14NTransform();
reference.AddTransform(c14n);

signedXml.AddReference(reference);

KeyInfo keyInfo = new KeyInfo();
keyInfo.AddClause(new KeyInfoX509Data(cert));

signedXml.KeyInfo = keyInfo;

signedXml.ComputeSignature();

XmlNode parentNode = xmlDoc.SelectSingleNode("/ns:TopLevelNode", namespaces);
parentNode.InsertAfter(xmlDoc.ImportNode(signedXml.GetXml(), true),
    parentNode.FirstChild);

if (xmlDoc.FirstChild is XmlDeclaration)
    xmlDoc.RemoveChild(xmlDoc.FirstChild);

XmlTextWriter xmltw = new XmlTextWriter("C:\\Development\\test2.xml",
    new UTF8Encoding(false));
xmlDoc.WriteTo(xmltw);
xmltw.Close();

I have tried validating the SignedXML in .NET and this seems to validate, but since it is the language it is written in, I am not putting to much trust in this.

My specification looks like this:

<Signature xmlns="NonStandard">
  <SignedInfo>
    <CanonicalizationMethod Algorithm="http://www.w3.org/TR/2001/REC-xml-c14n-20010315" />
    <SignatureMethod Algorithm="http://www.w3.org/2000/09/xmldsig#rsa-sha1" />
    <Reference URI="">
      <Transforms>
        <Transform Algorithm="http://www.w3.org/2000/09/xmldsig#enveloped-signature" />
        <Transform Algorithm="http://www.w3.org/TR/2001/REC-xml-c14n-20010315" />
      </Transforms>
      <DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1" />
      <DigestValue>…</DigestValue>
    </Reference>
  </SignedInfo>
  <SignatureValue>…</SignatureValue>
  <KeyInfo>
    <X509Data>
       <X509Certificate>…</X509Certificate>
    </X509Data>
  </KeyInfo>
</Signature>

Am I doing something obviously wrong? I am unsure of how important the Namespace is with regards to signing the XML, but since this seems to be a .NET "set in stone", I doubt this could be it?

È stato utile?

Soluzione

The above code works as intended, just if anyone wants to know how to sign XML (other than the numerous examples there already are). There was a problem with the WebService.

Best regards Andreas

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top