Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

like image 946
Mirko Avatar asked Nov 04 '16 09:11

Mirko


2 Answers

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));
like image 88
pedrofb Avatar answered Sep 24 '22 18:09

pedrofb


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) {
    //...

}
like image 29
Mirko Avatar answered Sep 21 '22 18:09

Mirko