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
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));
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) {
//...
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With