Getting certificate from XMLSignature in Java
I'm trying to get the certificate out of XMLSignature, get it's CRL DistributionPoint and verify if it's valid.
I have a digital document and signature file name, and that's how I get XMLSignature:
ZipFile zipFile = new ZipFile(dataFactory.getDataReader().getFileAdoc(adocFileName));
ZipEntry entry = zipFile.getEntry(signatureFileName);
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
dbf.setNamespaceAware(true);
Document doc = dbf.newDocumentBuilder().parse(zipFile.getInputStream(entry));
NodeList nl = doc.getElementsByTagNameNS(XMLSignature.XMLNS, "Signature");
if (nl.getLength() == 0)
{
throw new Exception("Cannot find Signature element");
}
XMLSignatureFactory fac = XMLSignatureFactory.getInstance("DOM");
DOMValidateContext valContext = new DOMValidateContext(new X509KeySelector(), nl.item(0));
ZipFileURIDereferencer dereferencer = new ZipFileURIDereferencer(zipFile);
valContext.setURIDereferencer(dereferencer)开发者_C百科;
XMLSignature signature = fac.unmarshalXMLSignature(valContext);
Now, how do I get Certificate or X509Certificate?
I have tried getting < X509Certificate > part:
NodeList sertificateNodeList = doc.getElementsByTagName("X509Certificate");
if (sertificateNodeList.getLength() == 0) {
throw new Exception("Cannot find X509Certificate element");
}
String certPart = sertificateNodeList.item(0).getFirstChild().getNodeValue();
System.out.println(certPart);
InputStream is = new ByteArrayInputStream(certPart.getBytes());
CertificateFactory cf = CertificateFactory.getInstance("X.509");
Certificate cert = cf.generateCertificate(is);
But that gives me:
java.security.cert.CertificateParsingException: invalid DER-encoded certificate data
Maybe I just need to somehow encode that InputStream is?
The signature.xml contains:
<X509Certificate>
MIIKVTCCCT2gAwIBAgIOY7W3f/J6VnsAAQAInYYwDQYJKoZIhvcNAQEFBQAwgbsxCzAJBgNVBAYT
AkxUMUAwPgYDVQQKEzdHeXZlbnRvanUgcmVnaXN0cm8gdGFybnliYSBwcmllIExSIFZSTSAtIGku
...
FWxieiI3KtGsVPYZ1/C7QHLv0SRMaCm/+qHuPSWh+L5YIcjBxQbD4bU2Q9soW7QshkRNRJOWSonK
Rw/cD4gWZDPte3V42qj6SZazsjDrGTFaGBg3
</X509Certificate>
Thanks!
InputStream is = new ByteArrayInputStream(**unbase64**(certPart));
hi Brutus, just unbase64 the X509Certificate value
I've managed to get some kind of certificate (X509CertImpl) and check it's validity, by using some code I've found online:
XMLSignature signature = fac.unmarshalXMLSignature(valContext);
KeyInfo keyInfo = signature.getKeyInfo();
Iterator iter = keyInfo.getContent().iterator();
X509CertImpl certImpl = null;
while (iter.hasNext()) {
XMLStructure kiType = (XMLStructure) iter.next();
if (kiType instanceof X509Data) {
X509Data xd = (X509Data) kiType;
Object[] entries = xd.getContent().toArray();
X509CRL crl = null;
for (int i = 0; ( i < entries.length); i++) {
if (entries[i] instanceof X509CRL) {
crl = (X509CRL) entries[i];
}
if (entries[i] instanceof X509CertImpl) {
certImpl = (X509CertImpl) entries[i];
try {
certImpl.checkValidity(signDate);
} catch (CertificateExpiredException expiredEx) {
System.out.println("CERTIFICATE EXPIRED!");
return 1;
} catch (CertificateNotYetValidException notYetValidEx) {
System.out.println("CERTIFICATE NOT VALID YET!");
return 0;
}
System.out.println("CERTIFICATE IS VALID!");
}
}
}
}
精彩评论