Java X509证书解析和验证

问题描述:

我试图在几个步骤中处理X509证书,并遇到一些问题。我是JCE的新手,所以我没有完全掌握所有内容。Java X509证书解析和验证

我们希望能够根据不同的编码(PEM,DER和PCKS7)解析几个不同的X509证书。我已经使用FireFox(证书包括链),以PEM和PCKS7格式从https://belgium.be导出了相同的证书。我已经离开那些不需要的问题

public List<X509Certificate> parse(FileInputStream fis) { 
    /* 
    * Generate a X509 Certificate initialized with the data read from the inputstream. 
    * NOTE: Generation fails when using BufferedInputStream on PKCS7 certificates. 
    */ 
    List<X509Certificate> certificates = null; 
     log.debug("Parsing new certificate."); 
     certificates = (List<X509Certificate>) cf.generateCertificates(fis); 
    return certificates; 
    } 

此代码几行了工作正常aslong我与一个FileInputStream而不是为PCKS7一个的BufferedInputStream,这已经是我觉得挺奇怪的工作吗?但我可以忍受它。

下一步是验证这些证书链。 1)检查所有证书是否有有效日期(简单) 2)使用OCSP验证证书链(如果证书中没有找到OCSP URL,则回退到CRL)。这是我不完全确定如何处理这个问题的地方。

我正在使用Sun JCE,但它似乎没有那么多文档可用(在示例中)?

我首先做了一个简单的实现,只检查链而不经过OCSP/CRL检查。

private Boolean validateChain(List<X509Certificate> certificates) { 
    PKIXParameters params; 
    CertPath certPath; 
    CertPathValidator certPathValidator; 
    Boolean valid = Boolean.FALSE; 

    params = new PKIXParameters(keyStore); 
    params.setRevocationEnabled(false); 

    certPath = cf.generateCertPath(certificates); 
    certPathValidator = CertPathValidator.getInstance("PKIX"); 

    PKIXCertPathValidatorResult result = (PKIXCertPathValidatorResult) 
    certPathValidator.validate(certPath, params); 

     if(null != result) { 
     valid = Boolean.TRUE; 
     } 
    return valid; 
} 

这是对我的PEM证书工作正常,但不是为PCKS7证书(相同的认证文件,只出口在其他格式)。 java.security.cert.CertPathValidatorException:路径不链接任何信任锚。

我能看到的唯一区别是CertPath的形成顺序是不一样的?我无法弄清楚发生了什么事情错了,所以我离开了这个现在并保持在与PEM证书去,但让我们称之为这个问题1)

我想要实现之后是OCSP检查。 显然,如果我启用OCSP使用:Security.setProperty(“ocsp.enable”,“true”);并设置params.setRevocationEnabled(true); 它应该能够自己找到OCSP URL,但似乎并不是这样。标准实施应该做什么(问题2)? java.security.cert.CertPathValidatorException:必须指定的OCSP响应

走出过去这个位置,我找到了一种方法来检索使用AuthorityInfoAccessExtension和这种证书的OCSP URL。

但在ocsp.url属性手动设置OCSP URL后,我发现了一个java.security.cert.CertPathValidatorException:OCSP响应错误:未经授权

好像我错过了很多必要的步骤,而很多在线参考文献说,设置ocsp.enable属性应该是你需要做的一切吗?

也许你们中的任何一个人都不能指导我完成整个过程?告诉我我完全错误的地方:)

如果没有找到OCSP,下一步将执行CRL检查,如果任何人都可以指出任何示例或向我展示一些文档,这也将非常感谢!

谢谢!

编辑: 因为它不是拿起自身的属性,我一直在试图利用对自己设置的所有属性如下:

// Activate OCSP 
     Security.setProperty("ocsp.enable", "true"); 
     // Activate CRLDP -- no idea what this is 
     Security.setProperty("com.sun.security.enableCRLDP", "true"); 

     X509Certificate target = (X509Certificate) certPath.getCertificates().get(0); 
     Security.setProperty("ocsp.responderURL","http://ocsp.pki.belgium.be/"); 
     Security.setProperty("ocsp.responderCertIssuerName", target.getIssuerX500Principal().getName()); 
     Security.setProperty("ocsp.responderCertSubjectName", target.getSubjectX500Principal().getName()); 
     Security.setProperty("ocsp.responderCertSerialNumber", target.getSerialNumber().toString(16)); 

这给出了一个例外: 的Java。 security.cert.CertPathValidatorException:找不到响应者的证书(使用OCSP安全属性进行设置)。

+0

OSCPChecker似乎在getOCSPServerURI方法中执行此操作:http://grepcode.com/file/repository.grepcode.com/java/root/jdk/openjdk/7u40-b43/sun/security/provider/certpath/OCSPChecker .java#OCSPChecker.getOCSPServerURI%28sun.security.x509.X509CertImpl%2Cjava.lang.String%29 – 2014-03-17 18:46:28

+0

在你的例子中'cf'是什么? – spy 2017-08-29 14:33:20

+0

这已经很久了,但我会说https://docs.oracle.com/javase/7/docs/api/java/security/cert/CertificateFactory.html – 2017-08-29 14:35:23

以供将来参考我的答案后,以我自己的问题(部分ATLEAST)

OCSP和CRL检查标准Java实现已经实现,没有必要为自定义代码或其他供应商(公元前,..)。它们默认是禁用的。

为了实现这一目标,你必须ATLEAST设置两个参数:

(PKIXParameters or PKIXParameterBuilder) params.setRevocationEnabled(true); 
Security.setProperty("ocsp.enable", "true"); 

这将激活OCSP检查,当你试图验证证书路径(PKIXCertPathValidatorResult.validate())。

当你想添加的回退检查CRL如果没有OCSP可用,添加aditional的属性:

System.setProperty("com.sun.security.enableCRLDP", "true"); 

我的很多问题正在发生,由于这样的事实,我必须支持不同的证书格式(PKCS7,PEM)。我的执行工作正常PEM,但由于PKCS7不保存证书的顺序链是有点困难(http://bugs.sun.com/view_bug.do?bug_id=6238093

X509CertSelector targetConstraints = new X509CertSelector(); 

targetConstraints.setCertificate(certificates.get(0)); 
// Here's the issue for PKCS7 certificates since they are not ordered, 
// but I havent figured out how I can see what the target certificate 
// (lowest level) is in the incoming certificates.. 

PKIXBuilderParameters params = new PKIXBuilderParameters(anchors, targetConstraints); 

希望这将成为其他人有用的话为好,也许有人能阐明了如何在一个无序的PKCS7列表中找到目标证书?