Search code examples
javaxmldigital-signaturexml-signatureenvelope

How to extract "original" content by xml-signed file


I'm dealing with XML-signature. As you know, there are three types of XML signatures: enveloped, enveloping, detached.

I found nice tutorials about how to use java standard API to sign/verify file but I would like to know how to extract the (almost) "original" content data. In particular:

1) After validating an Enveloped XML signed file, what is the right way to "get" the XML content without signature?

2) After validating an Enveloping XML signed file, what is the right way to "get" the "Object" node?

For "get" I mean writing on a separate physical file, cleaning signature (with standard API, if possible).

Thank you in advance,

kindly.

Mirko


Solution

  • Enveloped signature

    <yourxml>
       ...
       <Signature>....</Signature>
    </yourxml>
    

    The signature is a node of the XML document. After validating the XML Signature, find the node, remove it of DOM structure and save the document.

    // Instantiate the document to be signed.
    DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
    dbf.setNamespaceAware(true);
    Document doc = dbf.newDocumentBuilder().parse(new FileInputStream(xml));
    
    // Find Signature element.
    NodeList nl = doc.getElementsByTagNameNS(XMLSignature.XMLNS, "Signature");
    
    //... XML Signature validation
    
    //remove signature node from DOM
    nl.item(0).getParentNode().removeChild(nl.item(0));
    
    //write to file.
    OutputStream os = new FileOutputStream(outputFileName);
    TransformerFactory tf = TransformerFactory.newInstance();
    Transformer trans = tf.newTransformer();
    trans.transform(new DOMSource(doc), new StreamResult(os));
    

    Enveloping signature

    <Signature>
       <Object Id="object">
          <yourxml>...</yourxml>
        </Object>
     </Signature>
    

    You could apply the same technique. Find the Object node and save the first child to a file. But in this case, the XMLSignature provides getObjects method to get the signed objects

    //XMLSignature result of validation process
    XMLSignature signature = ...
    
    //Gets the node
    XMLObject xmlObject = (XMLObject)signature.getObjects().get(0);
    Node yourXmlNode = ((DOMStructure)xmlObject.getContent().get(0)).getNode();
    
    //Save to file
    OutputStream os = new FileOutputStream(outputFileName);
    TransformerFactory tf = TransformerFactory.newInstance();
    Transformer trans = tf.newTransformer();
    trans.transform(new DOMSource(yourXmlNode), new StreamResult(os));