Eu tenho alguns xmls que recebo por email que são xmls da SEFAZ, preciso validar Signature do xml para verificar se é válido o xml.
Estou fazendo a seguinte classe, entretanto ao verificar a tag Signature está sempre retornando 0.
private static void validarXMl(String xml) throws Exception {
DocumentBuilderFactory factorySignature = DocumentBuilderFactory.newInstance();
factorySignature.setNamespaceAware(true);
Document doc = DocumentBuilderFactory.newInstance().newDocumentBuilder()
.parse(new ByteArrayInputStream(xml.getBytes()));
NodeList nl = doc.getElementsByTagNameNS(XMLSignature.XMLNS, "Signature");
if (nl.getLength() == 0) {
//está sempre caindo nesse if, sempre ficando 0, sendo que no xml tem a tag Signature.
throw new Exception("Cannot find Signature element");
}
XMLSignatureFactory fac = XMLSignatureFactory.getInstance("DOM");
// Cria um DOMValidateContext
// Create a DOMValidateContext and specify a KeySelector
// and document context.
DOMValidateContext valContext = new DOMValidateContext
(new X509KeySelector(), nl.item(0));
XMLSignature signatures = fac.unmarshalXMLSignature(valContext);
// Valida a XMLSignature.
boolean coreValidity = signatures.validate(valContext);
// Check core validation status.
if (coreValidity == false) {
System.err.println("Signature failed core validation");
boolean sv = signatures.getSignatureValue().validate(valContext);
System.out.println("signature validation status: " + sv);
if (sv == false) {
// Check the validation status of each Reference.
Iterator<?> i = signatures.getSignedInfo().getReferences().iterator();
for (int j=0; i.hasNext(); j++) {
boolean refValid = ((Reference) i.next()).validate(valContext);
System.out.println("ref["+j+"] validity status: " + refValid);
}
}
} else {
System.out.println("Signature passed core validation");
}
}
Classe X509KeySelector
public class X509KeySelector extends KeySelector {
@Override
public KeySelectorResult select(KeyInfo keyInfo,
Purpose purpose,
AlgorithmMethod method,
XMLCryptoContext context)
throws KeySelectorException {
Iterator ki = keyInfo.getContent().iterator();
while (ki.hasNext()) {
XMLStructure info = (XMLStructure) ki.next();
if (!(info instanceof X509Data))
continue;
X509Data x509Data = (X509Data) info;
Iterator xi = x509Data.getContent().iterator();
while (xi.hasNext()) {
Object o = xi.next();
if (!(o instanceof X509Certificate))
continue;
final PublicKey key = ((X509Certificate)o).getPublicKey();
// Make sure the algorithm is compatible
// with the method.
if (algEquals(method.getAlgorithm(), key.getAlgorithm())) {
return new KeySelectorResult() {
public Key getKey() { return key; }
};
}
}
}
throw new KeySelectorException("No key found!");
}
static boolean algEquals(String algURI, String algName) {
if ((algName.equalsIgnoreCase("DSA") &&
algURI.equalsIgnoreCase(SignatureMethod.DSA_SHA1)) ||
(algName.equalsIgnoreCase("RSA") &&
algURI.equalsIgnoreCase(SignatureMethod.RSA_SHA1))) {
return true;
} else {
return false;
}
}
}