使用 CertPathValidator 进行签名验证,包括 CRL 撤销

Signature validation with CertPathValidator including CRL revocation

在验证签名的上下文中,我想在文档签名时验证签名证书的有效性。我意识到,如果我指定过去的日期,则不使用 CRL 撤销检查方法,而如果我使用当前时间或 null,则撤销检查工作正常。我正在使用下一个代码

 CertificateFactory cf = CertificateFactory.getInstance( "X.509" );
 CertPath certPath =    cf.generateCertPath( certs );
 CertPathValidator cpv = CertPathValidator.getInstance( "PKIX", "SUN" );
PKIXParameters params = new PKIXParameters( ks );
params.setDate( signingTime );
params.setRevocationEnabled( true );                
cpvResult = (PKIXCertPathValidatorResult) cpv.validate( certPath, params ); 

我已经启用了系统属性 EnabledCRLDP。 此外,OCSP 不是通用解决方案,因为它不适用于某些证书。

在过去的时间验证中有不使用 CRL 撤销方法的原因吗?

在这种情况下有什么方法可以强制使用 CRL?

证书颁发机构只有证书的当前状态。无法请求过去日期的状态:如果证书已过期,CA 可能已删除该日期颁发的 CRL,甚至可能已清除所有记录

因此只能使用在该日期发布的 CRL 或 OCSP 执行过去时间验证。您需要保留撤销证据以及将来使用的签名。(有特定的数字签名格式设计用于包含 AdES 等撤销证据)

我怀疑如果提供了过去的日期,CertPathValidator 的底层实现会禁用 CRL 请求。请注意,PKIX 未定义应如何检查吊销。见官方Java安全guide

The setRevocationEnabled method allows a caller to disable revocation checking. Revocation checking is enabled by default, since it is a required check of the PKIX validation algorithm. However, PKIX does not define how revocation should be checked. An implementation may use CRLs or OCSP, for example.

使用 java 8 您可以使用

设置所需的 CRL 集 and/or OCSP 响应
 params.setCertStores(certStoreList);. //store containing crls
 PKIXRevocationChecker rc =  (PKIXRevocationChecker)cpv.getRevocationChecker();
 rc.setOcspResponses(responses)

但是正如你所说,这种方法不适用于java6,所以我认为你可以禁用吊销检查并在验证证书链后手动实现OCSP和CRL验证。

例如使用它来验证使用 CRL 的证书

CertificateFactory cf = CertificateFactory.getInstance("X.509");
X509CRL crl = (X509CRL)cf.generateCRL(inStream); 
crl.isRevoked(certificate);

可以使用 bouncycastle 处理 OCSP 响应。看到这个问题OCSP response does not give Certificate Status(省略了请求ocsp的部分,因为你应该有一个本地响应存储)