I have an XML signature verification code below:
public static boolean isXmlDigitalSignatureValid(String xmlString) throws Exception {
boolean validFlag = false;
String pubicKeyFilePath = "src/main/resources/keys/publickey.key";
Document doc = convertStringToDocument(xmlString);
NodeList nl = doc.getElementsByTagNameNS(XMLSignature.XMLNS, "Signature");
if (nl.getLength() == 0) {
throw new Exception("No XML Digital Signature Found, document is discarded");
}
PublicKey publicKey = new CryptoUtil().getStoredPublicKey(pubicKeyFilePath);
DOMValidateContext valContext = new DOMValidateContext(publicKey, nl.item(0));
XMLSignatureFactory fac = XMLSignatureFactory.getInstance("DOM");
XMLSignature signature = fac.unmarshalXMLSignature(valContext);
validFlag = signature.validate(valContext);
return validFlag;
}
But there is a problem. Im sure that doc file has signature part cause I'm printing it. But
NodeList nl = doc.getElementsByTagNameNS(XMLSignature.XMLNS, "Signature");
cant find the signature part so
n1.item(0)
is null and I have the exception I mentioned in the header.
I figure it out what going on. My XMLReader method wasn't working properly. Yes it was returning string exactly but missing some point in bytes. So I change it a little.
First I read and convert to Doc file
public static Document getXmlDocument(String xmlFilePath) {
Document doc = null;
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
dbf.setNamespaceAware(true);
try {
doc = dbf.newDocumentBuilder().parse(new FileInputStream(xmlFilePath));
} catch (ParserConfigurationException ex) {
ex.printStackTrace();
} catch (FileNotFoundException ex) {
ex.printStackTrace();
} catch (SAXException ex) {
ex.printStackTrace();
} catch (IOException ex) {
ex.printStackTrace();
}
return doc;
}
Then I convert doc to string.
public static Document convertStringToDocument(String xmlStr) {
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
factory.setNamespaceAware(true);
DocumentBuilder builder;
try
{
builder = factory.newDocumentBuilder();
Document doc = builder.parse( new InputSource( new StringReader( xmlStr ) ) );
return doc;
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
And my final xmlReader Function is :
public static String xmlReader(String path){
return convertDocumentToString(XmlDigitalSignatureGenerator.getXmlDocument(path));
}
This is the only way that I convert an XML file to string properly