【问题标题】:How to check revocation status of X509Certificate chain using JAVA?如何使用 JAVA 检查 X509Certificate 链的吊销状态?
【发布时间】:2016-11-01 13:39:33
【问题描述】:

我有一系列 X509Certificates 以用户证书开头并以受信任的 CA 证书结尾。为了测试,我正在尝试使用 Google 证书。

我想检查证书链中每个证书的吊销状态。

我正在使用以下代码:

public static boolean isCertChainValid(ArrayList<X509Certificate> certificateList) {

    try {

        CertificateFactory certificateFactory = CertificateFactory.getInstance("X.509");

        CertPath certPath = certificateFactory.generateCertPath(certificateList);

        CertPathValidator validator = CertPathValidator.getInstance("PKIX");

        KeyStore keystore = KeyStore.getInstance("JKS");
        InputStream is = new FileInputStream(System.getProperty("java.home") + "/lib/security/" + "cacerts");
        keystore.load(is, "changeit".toCharArray());

        PKIXParameters params = new PKIXParameters(keystore);

        params.setRevocationEnabled(true);

        Security.setProperty("ocsp.enable", "true");
        System.setProperty("com.sun.net.ssl.checkRevocation", "true");
        System.setProperty("com.sun.security.enableCRLDP", "true");

        PKIXCertPathValidatorResult r = (PKIXCertPathValidatorResult) validator.validate(certPath, params);
        return true;
    } catch (CertificateException e) {
        throw new RuntimeException(e);

    } catch (NoSuchAlgorithmException e) {
        throw new RuntimeException(e);

    } catch (KeyStoreException e) {
        throw new RuntimeException(e);

    } catch (IOException e) {
        throw new RuntimeException(e);

    } catch (InvalidAlgorithmParameterException e) {
        throw new RuntimeException(e);

    } catch (CertPathValidatorException e) {
        throw new RuntimeException(e);
    }
}

这是我获取证书列表的方式:

public static void main(String args[]) throws Exception {

    CertVal certVal = new CertVal(new File("/home/varun/Documents/SampleCerts/google.pem"), "X.509");
    X509Certificate cert = (X509Certificate) certVal.getCert();

    certVal = new CertVal(new File("/home/varun/Documents/SampleCerts/google.int.pem"), "X.509");
    X509Certificate int_cert = (X509Certificate) certVal.getCert();

    certVal = new CertVal(new File("/home/varun/Documents/SampleCerts/google.root.pem"), "X.509");
    X509Certificate root_cert = (X509Certificate) certVal.getCert();

    System.out.println(cert.toString());

    ArrayList<X509Certificate> cList = new ArrayList<>();
    cList.add(cert);
    cList.add(int_cert);
    cList.add(root_cert);

    System.out.println(isCertChainValid(cList));
}

google.pem, google.int.pem, google.root.pem 分别是浏览器中通过导出选项获得的最终证书、中间证书和根证书。

CertVal 是我制作的一个类,它将从文件中导入证书,其方法将返回证书对象。它工作正常,并且很好地打印了最终证书,如下所示:

[ [ 版本:V3 主题:CN=*.google.com,O=Google Inc,L=Mountain 查看,ST=加利福尼亚,C=美国签名算法:SHA256withRSA,OID = 1.2.840.113549.1.1.11

密钥:Sun EC 公钥,256 位公共 x 坐标: 46177506158937302063723158048612066903199153823785912505310712817097913459047 公共 y 坐标: 113809014154880901150321029617294838083005712679903474974082163637608868220331 参数:secp256r1 [NIST P-256, X9.62 prime256v1] (1.2.840.10045.3.1.7) 有效期:[来自:2016 年 6 月 16 日星期四 14:07:32 IST, 至:Thu Sep 08 13:59:00 IST 2016] 发行人:CN=Google Internet Authority G2,O=Google Inc,C=US 序列号:[
51e47ed1 28a4436e]

证书扩展:9 [1]:ObjectId:1.3.6.1.5.5.7.1.1 Criticality=false AuthorityInfoAccess [ [ accessMethod: caIssuers 访问位置:URIName:http://pki.google.com/GIAG2.crt
accessMethod: ocsp accessLocation: URIName: http://clients1.google.com/ocsp]]

[2]: ObjectId: 2.5.29.35 Criticality=false AuthorityKeyIdentifier [ 密钥标识符 [ 0000: 4A DD 06 16 1B BC F6 68 B5 76 F5 81 B6 BB 62 1A J......h.v....b. 0010: BA 5A 81 2F
.Z./]]

[3]:ObjectId:2.5.29.19 Criticality=true BasicConstraints:[
CA:false PathLen: 未定义]

[4]:ObjectId:2.5.29.31 Criticality=false CRLDistributionPoints [
[分发点: [URIName:http://pki.google.com/GIAG2.crl]]]

[5]:ObjectId:2.5.29.32 Criticality=false CertificatePolicies [
[CertificatePolicyId: [1.3.6.1.4.1.11129.2.5.1] [] ]
[CertificatePolicyId: [2.23.140.1.2.2] [] ] ]

[6]:ObjectId:2.5.29.37 Criticality=false ExtendedKeyUsages [
serverAuth clientAuth ]

[7]:ObjectId:2.5.29.15 Criticality=false KeyUsage [
数字签名]

[8]:ObjectId:2.5.29.17 Criticality=false SubjectAlternativeName [
DNSName:*.google.com DNSName:*.android.com DNSName: *.appengine.google.com DNSName:*.cloud.google.com DNSName:*.google-analytics.com DNSName:*.google.ca DNSName:*.google.cl DNSName:*.google.co.in DNSName: *.google.co.jp DNS 名称: *.google.co.uk DNSName: *.google.com.ar DNSName: *.google.com.au DNSName: *.google.com.br DNSName: *.google.com.co DNSName: *.google.com.mx DNSName:*.google.com.tr DNSName:*.google.com.vn DNSName:*.google.de DNSName:*.google.es DNSName:*.google.fr
DNSName:*.google.hu DNSName:*.google.it DNSName:*.google.nl
DNSName:*.google.pl DNSName:*.google.pt DNSName: *.googleadapis.com DNSName:*.googleapis.cn DNSName:*.googlecommerce.com DNSName:*.googlevideo.com DNSName:*.gstatic.cn DNSName:*.gstatic.com DNSName:*.gvt1.com DNSName:* .gvt2.com DNSName:*.metric.gstatic.com DNSName:*.urchin.com DNSName:*.url.google.com DNSName:*.youtube-nocookie.com DNSName: *.youtube.com DNSName:*.youtubeeducation.com DNSName:*.ytimg.com DNSName:android.clients.google.com DNSName:android.com DNSName: g.co DNSName:goo.gl DNSName:google-analytics.com DNSName: google.com DNS 名称:googlecommerce.com DNS 名称:urchin.com
DNSName: www.goo.gl DNSName: youtu.be DNSName: youtube.com
DNS 名称:youtubeeducation.com]

[9]:ObjectId:2.5.29.14 关键性 = 假 SubjectKeyIdentifier [ 密钥标识符 [ 0000: EE 4B 83 40 44 28 0A 6A 01 4D 55 D0 A4 A7 5F 1E .K.@D(.j.MU..._. 0010: DF 60 F2 1E
.`.. ] ]

] 算法:[SHA256withRSA] 签名:0000:38 89 81 D8 57 DA 3C C7 60 EA BA 6B 08 D4 92 47 8...W.<.>..k...G 0010: 60 AA B1 4B 39 34 1C E4 7B CC 71 1F 28 8F 07 82..K94....q.(... 0020: D7 04 3F CC 12 B7 9E DF 9F 13 D4 5A 5A 30 31 1F ..?........ZZ01。 0030: A5 41 BE 9A 60 27 EE AF 28 A8 BC 21 2F 65 31 BF .A..'..(..!/e1. 0040: A5 7D D6 D4 86 89 27 7F F6 3B 28 D6 16 AA 60 31 ......'..;(...1 0050:3D CD 67 97 84 22 43 2F B0 53 84 87 8C 47 44 5C =.g.."C/.S...GD\ 0060: EF 16 7A 73 2F 37 CB 39 48 3C F2 87 C5 77 82 A0 ..zs/7.9H<...w.. c6 a8 cc .. c1 bc b1 bb b6 ..........z.4... c4 db ae b7 f9 e7 .7 ce b0 f2 ac c2 ...u.h.9...h.... e8 d4 d0 fb ......ei cf d6 e6 f4 ...... f8 c5 df a5 i.. e1 a2 a1 c8 bf e4 . eb d7 bd.......>

]

正如在证书例外 9:[1] 和 [2] 中看到的,OSCP URL 和 CRL URL 都可用于证书。这两个东西也在中间证书中,但它们在根证书中没有,这是合理的,因为它们不需要它们。

我的问题是当我运行上面的程序时,它给了我以下错误。

线程“主”java.lang.RuntimeException 中的异常: java.security.cert.CertPathValidatorException:证书没有 指定 OCSP 响应者 test_data.ImportAndTestCert.isCertChainValid(ImportAndTestCert.java:157) 在 test_data.ImportAndTestCert.main(ImportAndTestCert.java:72) 引起 通过:java.security.cert.CertPathValidatorException:证书确实 不指定 OCSP 响应者 sun.security.provider.certpath.PKIXMasterCertPathValidator.validate(PKIXMasterCertPathValidator.java:135) 在 sun.security.provider.certpath.PKIXCertPathValidator.validate(PKIXCertPathValidator.java:219) 在 sun.security.provider.certpath.PKIXCertPathValidator.validate(PKIXCertPathValidator.java:140) 在 sun.security.provider.certpath.PKIXCertPathValidator.engineValidate(PKIXCertPathValidator.java:79) 在 java.security.cert.CertPathValidator.validate(CertPathValidator.java:292) 在 test_data.ImportAndTestCert.isCertChainValid(ImportAndTestCert.java:126) ... 1 更多

如果我评论Security.setProperty("ocsp.enable", "true");,它会给我以下错误:

线程“主”java.lang.RuntimeException 中的异常: java.security.cert.CertPathValidatorException:无法确定 撤销状态 test_data.ImportAndTestCert.isCertChainValid(ImportAndTestCert.java:157) 在 test_data.ImportAndTestCert.main(ImportAndTestCert.java:72) 引起 作者:java.security.cert.CertPathValidatorException:无法确定 撤销状态 sun.security.provider.certpath.PKIXMasterCertPathValidator.validate(PKIXMasterCertPathValidator.java:135) 在 sun.security.provider.certpath.PKIXCertPathValidator.validate(PKIXCertPathValidator.java:219) 在 sun.security.provider.certpath.PKIXCertPathValidator.validate(PKIXCertPathValidator.java:140) 在 sun.security.provider.certpath.PKIXCertPathValidator.engineValidate(PKIXCertPathValidator.java:79) 在 java.security.cert.CertPathValidator.validate(CertPathValidator.java:292) 在 test_data.ImportAndTestCert.isCertChainValid(ImportAndTestCert.java:126) ... 1 更多

我错过了什么吗?

感谢您的帮助。

【问题讨论】:

    标签: java security ssl certificate x509certificate


    【解决方案1】:

    我发现了问题。

    造成所有麻烦的是 certpath 中存在根证书。

    根证书不包含 CRL 和 OSCP 链接。不断更新存储库是受信任证书存储库或 TrustStore 的工作。

    由于根证书不包含 CRL 和 OSCP 链接,因此会出现类似的错误

    线程“主”java.lang.RuntimeException 中的异常: java.security.cert.CertPathValidatorException:无法确定 撤销状态在

    线程“主”java.lang.RuntimeException 中的异常: java.security.cert.CertPathValidatorException:证书没有 指定 OCSP 响应者在

    简而言之,要检查证书链中证书的吊销状态,需要排除根证书。验证器算法可以确定最后一个中间证书是否由根 CA 签名。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2021-03-31
      • 1970-01-01
      • 2016-11-13
      • 2011-07-18
      • 2021-07-23
      • 2011-10-15
      • 2018-01-15
      • 1970-01-01
      相关资源
      最近更新 更多