从Java中获取XMLSignature证书

时间:2010-12-02 13:59:00

标签: java certificate digital-signature x509certificate

我正在尝试从XMLSignature中获取证书,获取它的CRL DistributionPoint并验证它是否有效。

我有一个数字文档和签名文件名,这就是我获取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);

XMLSignature signature = fac.unmarshalXMLSignature(valContext);

现在,我如何获得证书或X509Certificate?

我尝试过< X509证书>部分:

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);

但这给了我:

java.security.cert.CertificateParsingException: invalid DER-encoded certificate data

也许我只需要以某种方式编码InputStream是什么?

signature.xml包含:

<X509Certificate>
MIIKVTCCCT2gAwIBAgIOY7W3f/J6VnsAAQAInYYwDQYJKoZIhvcNAQEFBQAwgbsxCzAJBgNVBAYT
AkxUMUAwPgYDVQQKEzdHeXZlbnRvanUgcmVnaXN0cm8gdGFybnliYSBwcmllIExSIFZSTSAtIGku
...
FWxieiI3KtGsVPYZ1/C7QHLv0SRMaCm/+qHuPSWh+L5YIcjBxQbD4bU2Q9soW7QshkRNRJOWSonK
Rw/cD4gWZDPte3V42qj6SZazsjDrGTFaGBg3
</X509Certificate>

谢谢!

2 个答案:

答案 0 :(得分:2)

InputStream is = new ByteArrayInputStream(**unbase64**(certPart));

在Brutus中,只需unbase64 X509Certificate值

答案 1 :(得分:1)

我设法获得某种证书(X509CertImpl),并使用我在网上找到的一些代码检查它的有效性:

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!");                        
            }
        }
    }
}