Boa tarde.
Gostaria que me ajudassem na validação de uma assinatura digital de um XML, uma detached signature, que traz uma chain certificates, ou seja três certificados. Gostaria de saber como usar esses tres certificados para validar a chave do XML, considerando que tenho a chave pública numa keystore ou guardada num ficheiro. Deixo o que tenho feito e se alguem tiver um exemplo de como fazer agradeço! Valeu!!!
FICHEIRO XML:
(…)
<Signature xmlns="http://www.w3.org/2000/09/xmldsig#">
- <SignedInfo xmlns="http://www.w3.org/2000/09/xmldsig#">
<CanonicalizationMethod Algorithm="http://www.w3.org/TR/2001/REC-xml-c14n-20010315" />
<SignatureMethod Algorithm="http://www.w3.org/2000/09/xmldsig#rsa-sha1" />
- <Reference URI="#3780197">
<DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1" />
<DigestValue>9BoB5VASWdKHLbG0I81B7UwDU/k=</DigestValue>
</Reference>
</SignedInfo>
<SignatureValue>(...)</SignatureValue>
- <KeyInfo>
- <X509Data>
<X509Certificate>(...)</X509Certificate>
<X509Certificate>(...)</X509Certificate>
<X509Certificate>(...)</X509Certificate> </X509Data>
</KeyInfo>
</Signature>
O meu código, que vai buscar os certificados do XML, as chaves na minha keystore, mas penso que falta validar a assinatura do XML:
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
InputSource inStream = new InputSource();
inStream.setCharacterStream(new StringReader(xmlWithSignature));
dbf.setNamespaceAware(true);
//****************************************
// DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
try{
if(getCertParameters()){
//Parse do XML
Document docXML = dbf.newDocumentBuilder().parse(inStream);
//Obtencao do elemento que contém a assinatura digital
Element nscontext = XMLUtils.createDSctx(docXML, "ds",
Constants.SignatureSpecNS);
Element sigElement = (Element) XPathAPI.selectSingleNode(docXML,
"//ds:Signature[1]", nscontext);
org.apache.xml.security.signature.XMLSignature signatureXML = new org.apache.xml.security.signature.XMLSignature(sigElement,"");
KeyInfo ki = (KeyInfo) signatureXML.getKeyInfo();
LogI.log(dbgLevel, "validateXMLSignature:ki->" + ki);
if (ki != null) {
X509Data x509DataItem = (X509Data) ki.itemX509Data(0);
if (ki.containsX509Data()) {
//Obter os varios certificados que compoem a assinatura
X509Certificate[] certs = getX509Certs(signatureXML);
X509Certificate cert;
if (certs == null || certs.length<=0){
return false;
}else{
for (int i=0;i< certs.length;i++){
cert = certs[i];
if (cert != null) {
//Gets the public key from this certificate
//PublicKey pk = cert.getKey();
tokenKeyStore = KeyStore.getInstance(keyStoreType);
if (tokenKeyStore == null) {
return false;
} else{
LogI.log(dbgLevel, "getSignatureKeyPair: Get key store!");
}
FileInputStream in = new FileInputStream(absolutePathFiles + keyStore);
tokenKeyStore.load(in, keyStorePass.toCharArray());
PublicKey pk = getPublicKey(tokenKeyStore, keyAlias, keyStorePass.toCharArray());
if (pk == null) {
return false;
}
LogI.log(dbgLevel, "validateXMLSignature:pk:" + pk.toString());
DOMValidateContext valContext = new DOMValidateContext(pk,sigElement);
javax.xml.crypto.dsig.XMLSignature signature = fac.unmarshalXMLSignature(valContext);
boolean coreValidity = signature.validate(valContext);
+ " é "
+ (coreValidity
? "válida!"
: "inválida !!!!!"));
if (coreValidity){
return true;
}else{
return false;
}
} else {
return false;
}
}
}
}else{
return false;
}
}else{
return false;
}
}else{
return false;
}
EDIT (Moderador) Por favor, lembre-se de usar as tags [ code ] para podermos visualizar seu código.