【问题标题】:Getting certificate from XMLSignature in Java从 Java 中的 XMLSignature 获取证书
【发布时间】:2011-05-19 03:46:24
【问题描述】:

我正在尝试从 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?

我已尝试获取 部分:

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: 无效的 DER 编码证书数据

也许我只需要以某种方式对 InputStream 进行编码?

signature.xml 包含:

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

谢谢!

【问题讨论】:

    标签: java certificate digital-signature x509certificate


    【解决方案1】:
    InputStream is = new ByteArrayInputStream(**unbase64**(certPart));
    

    嗨,Brutus,只需 unbase64 X509Certificate 值

    【讨论】:

      【解决方案2】:

      通过使用我在网上找到的一些代码,我设法获得了某种证书 (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!");                        
                  }
              }
          }
      }
      

      【讨论】:

      • 现在你可以让代码在每行插入至少 4 个前导空格。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2012-05-26
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多