views:

185

answers:

1

I have a XML file that looks like this

<Licence>
      <Name>Test company</Name>
      <Version>1.1.1.1</Version>
      <NumberOfServer>2</NumberOfServer>
</Licence>

I then use a previous generated private key to sign the XML file using the foloowing code

private void SignFile(XmlDocument doc)
{
    SignedXml signedXml = new SignedXml(doc2);

    _cryptoServiceProvider.FromXmlString(XmlDocument.Load("private.key").Root.ToString());

    signedXml.SigningKey = _cryptoServiceProvider;

    Signature XMLSignature = signedXml.Signature;

    Reference reference = new Reference("");

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

    XMLSignature.SignedInfo.AddReference(reference);

    signedXml.ComputeSignature();

    XmlElement xmlDigitalSignature = signedXml.GetXml();

    doc.DocumentElement.AppendChild(doc2.ImportNode(xmlDigitalSignature, true));

    doc.Save("signed.xml");
}

I get a file looking like this and that validates with the public key!

<Licence>
  <Name>Test company</Name>
  <Version>1.1.1.1</Version>
  <NumberOfServer>2</NumberOfServer>
  <Signature xmlns="http://www.w3.org/2000/09/xmldsig#"&gt;
    <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" />
        </Transforms>
        <DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1" />
        <DigestValue>tmGyr97mgGDviRpzcWjpMdNNMSI=</DigestValue>
      </Reference>
    </SignedInfo>
    <SignatureValue>Vc5R/OWiup4Rv7+1Tu8Ino83P0mh6npLkNYEaq0QVa6j+OvISOPERO57EllCQWdB1Lgjc7B+lmV4JiSvdfovkldhNZb4+iFgdrI+qOdSEIsBk/KhGS93PfekhDd3qirGerpeGbLAEqZ36jT0aT/QruZXpOX6Y6H5fqGj4prUZaM=</SignatureValue>
  </Signature>
</Licence>

BUT do I have to have the SignedInfo field in there and how can I get rid of it?

I use something like this to validate.

    _cryptoServiceProvider.FromXmlString(XDocument.Load("public.key").Root.ToString());

    XmlDocument doc = new XmlDocument();
    doc.Load("signed.xml");

    SignedXml signedXml = new SignedXml(doc);

    XmlNodeList nodeList = doc.GetElementsByTagName("Signature");
    signedXml.LoadXml((XmlElement)nodeList[0]);

    bool valid = signedXml.CheckSignature(_cryptoServiceProvider);
+1  A: 

No, you can't remove the SignedInfo element. There are a couple of reasons:

  1. It is required by the XML Signature Schema. If you remove it, software that supports XML Signature will break.
  2. The SignatureValue is computed over SignedInfo. If SignedInfo is absent, there is nothing to verify.

In a license file, where the message verifier might know the digest algorithm and other parameters though some "out-of-band" means, I suppose you could argue that the verifier could reconstruct the SignerInfo structure. But, it seems hard to justify breaking the standard and doing the extra work required.

erickson
OK. I kind thought so to but somehow convinced myself into believing it was easier that it was. Thanks. Nice answer.
Riri