How to extract "original" content by xml-signed file
Asked Answered
M

2

6

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

Michaelamichaele answered 4/11, 2016 at 9:3 Comment(0)
B
4

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));
Barbabra answered 4/11, 2016 at 13:41 Comment(0)
M
1

In the @pedrofb answer for the enveloping case, the code works if object data is XML-structured. However I have a flat data in the object node, so I obtain the original data content using similar technique:

NodeList nl = doc.getElementsByTagNameNS(XMLSignature.XMLNS, "Object");
if (nl.getLength() == 0) {
    throw new Exception("*** Cannot find Object element");
}
final String data = nl.item(0).getTextContent();

try {
    File target = new File("/path/output.dat");

    FileWriter writer = new FileWriter(target);
    BufferedWriter bufferedWriter = new BufferedWriter(writer, 8192);
    bufferedWriter.write(data);

    //flush & close writers
    //...

} catch (Exception e) {
    //...

}
Michaelamichaele answered 7/11, 2016 at 15:25 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.