xmldigital-signaturexades4j

XAdES internally detached signature


I want to create a file that contains multiple independent signatures referencing the same data. I want the data to be stored in the output XML file, as a sibling to ds:Signature elements, like below (only with multiple ds:Signature elements):

<?xml version="1.0" encoding="UTF-8"?>
<internally-detached>
  <ds:Signature xmlns:ds="http://www.w3.org/2000/09/xmldsig#">
    <ds:SignedInfo>
      <ds:CanonicalizationMethod 
         Algorithm="http://www.w3.org/TR/2001/REC-xml-c14n-20010315"/>
      <ds:SignatureMethod 
         Algorithm="http://www.w3.org/2000/09/xmldsig#rsa-sha1"/>
      <ds:Reference URI="#data">
        <ds:DigestMethod 
          Algorithm="http://www.w3.org/2000/09/xmldsig#sha1"/>
        <ds:DigestValue/>
      </ds:Reference>
    </ds:SignedInfo>
    <ds:SignatureValue/>
  </ds:Signature>

  <document Id="data">
     <title>title</title>
     <author>writer</author>
     <date>today</date>
     <content>
        <para>First paragraph</para>
        <para>Second paragraph</para>
     </content>
  </document>
</internally-detached>

Source: https://msdn.microsoft.com/en-us/library/ms759193(v=vs.85).aspx (I am aware that the site does not mention XAdES standard).

I tried to apply this to a valid enveloping XAdES signature and putting the referenced ds:Object node outside the ds:Signature element, but the verification software returns an error (referenced node was not found), and the xades4j verification module fails after encountering the </internally-detached> tag.

Is an internally detached signature possible with XAdES? If so, how can I achieve that?

I know that multiple signatures are possible when the data is stored in a separate file: each signature's SignedProperties element must contain SignedDataObjectProperties with ObjectReference, and the URI in SignedInfo's Reference element should point to the file.


Solution

  • That's certainly possible with XAdES signatures, since they are also "regular" XML signatures.

    I'm not sure what you mean by "xades4j doesn't even allow a root node other than ds:Signature"; your objective can be easily achieved.

    Assuming you have the base XML document without any signatures (either from a file or created using DOM APIs):

    <internally-detached>
      <document Id="data">
         <title>title</title>
         <author>writer</author>
         <date>today</date>
         <content>
            <para>First paragraph</para>
            <para>Second paragraph</para>
         </content>
      </document>
    </internally-detached>
    

    Having this and, lets say, 2 differently configured instances of XadesSigner, you can do something like:

    XadesSigner signer1 = ...;
    XadesSigner signer2 = ...;
    Document doc = ...; // your base XML
    Element signaturesParent = doc.getDocumentElement();
    
    SignedDataObjects objs = new SignedDataObjects(new DataObjectReference("#data"));
    signer1.sign(obj, signaturesParent);
    signer2.sign(obj, signaturesParent);
    

    Just beware that you need to define the "data" element's Id attribute as its XML ID.

    This should produce a document similar to:

    <internally-detached>
      <ds:Signature xmlns:ds="http://www.w3.org/2000/09/xmldsig#">
      ...
      </ds:Signature>
      <ds:Signature xmlns:ds="http://www.w3.org/2000/09/xmldsig#">
      ...
      </ds:Signature>
      <document Id="data">
         <title>title</title>
         <author>writer</author>
         <date>today</date>
         <content>
            <para>First paragraph</para>
            <para>Second paragraph</para>
         </content>
      </document>
    </internally-detached>