I have 2 portions of XML data which I have to canonize and create a digest:
<header authenticate="true">
<static>
<HostID>MMM</HostID>
<TransactionID>98B230CF5FB220FD75FE916949378C2F</TransactionID>
</static>
<mutable>
<TransactionPhase>Receipt</TransactionPhase>
</mutable>
</header>
and
<TransferReceipt authenticate="true">
<ReceiptCode>0</ReceiptCode>
</TransferReceipt>
If I just concatenate both strings and send them as byte[] to the canonnizer I get an exception:
org.xml.sax.SAXParseException; lineNumber: 9; columnNumber: 15; Markup im Dokument nach dem Root-Element muss ordnungsgemõ▀ formatiert sein.
at com.sun.org.apache.xerces.internal.parsers.DOMParser.parse(DOMParser.java:257)
at com.sun.org.apache.xerces.internal.jaxp.DocumentBuilderImpl.parse(DocumentBuilderImpl.java:338)
at org.apache.xml.security.c14n.Canonicalizer.canonicalize(Unknown Source)
at de.martinm.tools.Utils.DSTools.canonize_data(DSTools.java:141)
at de.martinm.tools.Utils.DSTools.getDigest(DSTools.java:244)
at de.martinm.tools.EBICS.EBICSKernel.send_ack(EBICSKernel.java:1039)
at de.martinm.tools.EBICS.EBICSKernel.process(EBICSKernel.java:1135)
at de.martinm.tools.EBICS.EBICSKernel.main(EBICSKernel.java:1145)
How do have to concatenate the data so that it can be canonized and after sending over the internet, the receiver can validate the digest?
I know, that the data is not xml valid as it has no single root element.
I cannot find a description how the data has to be formated.
Here is the code:
public byte[] getDigest(byte[] data) {
byte[] hash = null;
String algorithm="SHA-256";
try {
MessageDigest digest = MessageDigest.getInstance(algorithm);
byte[] canonical_data = canonize_data(data);
hash = digest.digest(canonical_data);
logger.debug("hash created: {}", Hex.encodeHexString(hash));
} catch (NoSuchAlgorithmException e) {
logger.error(algorithm, e);
};
return hash;
}
public byte[] canonize_data(byte[] data) {
byte[] canonical_data=null;
try {
Canonicalizer c14n = Canonicalizer.getInstance(Canonicalizer.ALGO_ID_C14N_OMIT_COMMENTS);
canonical_data = c14n.canonicalize(data);
} catch (InvalidCanonicalizerException | CanonicalizationException | ParserConfigurationException | IOException | SAXException e) {
logger.error(Canonicalizer.ALGO_ID_C14N_OMIT_COMMENTS, e);
}
logger.debug("data canonized");
return canonical_data;
}