Как извлечь исходный контент из файла с подписью xml

Я имею дело с XML-подписью. Как известно, XML-подписи бывают трех типов: конвертированные, конвертирующие и отдельные.

Я нашел хорошие учебные пособия о том, как использовать стандартный API Java для подписи/проверки файла, но я хотел бы знать, как извлечь (почти) «исходные» данные содержимого. Особенно:

1) После проверки подписанного XML-файла в оболочке, как правильно "получить" XML-контент без подписи?

2) После проверки файла с подписью Enveloping XML, как правильно "получить" узел "Object"?

Под «получить» я подразумеваю запись в отдельный физический файл, очистку подписи (по возможности стандартным API).

Заранее спасибо,

любезно.

Мирко


person Mirko    schedule 04.11.2016    source источник


Ответы (2)


Подпись в конверте

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

Подпись — это узел XML-документа. После проверки подписи XML найдите узел, удалите его из структуры DOM и сохраните документ.

// 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));

Подпись в конверте

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

Вы можете применить ту же технику. Найдите узел Object и сохраните первого потомка в файл. Но в этом случае XMLSignature предоставляет метод getObjects для получения подписанных объектов.

//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));
person pedrofb    schedule 04.11.2016

В ответе @pedrofb для охватывающего случая код работает, если данные объекта имеют XML-структуру. Однако у меня есть плоские данные в объектном узле, поэтому я получаю исходное содержимое данных, используя аналогичную технику:

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

}
person Mirko    schedule 07.11.2016