如何使用JAVA检查X509证书链的吊销状态?

Var*_*val 1 java security ssl certificate x509certificate

我有一连串的X509证书,以用户证书开头,以受信任的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);
    }
}
Run Code Online (Sandbox Code Playgroud)

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

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));
}
Run Code Online (Sandbox Code Playgroud)

google.pem,google.int.pem,google.root.pem是分别使用浏览器中的export选项获得的最终证书,中间证书和根证书。

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

[[版本:V3主题:CN = *。google.com,O = Google Inc,L = Mountain View,ST = California,C = US签名算法:SHA256withRSA,OID = 1.2.840.113549.1.1.11

密钥:Sun EC公钥,256位公钥x坐标:46177506158937302063723158048612066903199153823785912505310712817097913459047 public y coord:113809014154880901150321029617294838083005712679903474974082163637608868220331参数:secp256r1 [NIST P-256,X9.62 Prime(1.6.2.1.4)。[From 1.4.6.hu. [16.1.2.16。 14:07:32 IST 2016,收件人: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 accessLocation:URIName:http :
//pki.google.com/GIAG2.crt,accessMethod:ocsp accessLocation :URI名称:http ://clients1.google.com/ocsp ]]

[2]:ObjectId:2.5.29.35 Criticality = false AuthorityKeyIdentifier [KeyIdentifier [0000:4A DD 06 16 1B BC F6 68 B5 76 F5 81 B6 BB 62 1A J ...... hv ... b。0010:BA 5A 81 2F
.Z。/]]

[3]:ObjectId:2.5.29.19 Criticality = true BasicConstraints:[
CA:false PathLen:undefined]

[4]:ObjectId:2.5.29.31 Criticality = false CRLDistributionPoints [
[DistributionPoint:[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 [
DigitalSignature]

[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 DNS名称:* .google.ca DNS名称:* .google.cl DNS名称:* .google.co.in DNS名称:* .google.co.jp DNS名称:* .google.co.uk DNS名称:*。 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 DNS名称:* .gvt1.com DNS名称:* .gvt2.com DNS名称:* .metric.gstatic.com DNS名称:* .urchin.com DNS名称:* .url.google.com DNS名称:* .youtube -nocookie.com DNS名称:* .youtube.com DNS名称:* .youtubeeducation.com DNS名称:* .ytimg.com DNS名称:android.clients.google.com DNS名称:android.com DNS名称:g.co DNS名称:goo.gl DNS名称:google-analytics.com DNS名称:google.com DNS名称:googlecommerce.com DNS名称:urchin.com
DNS名称:www.goo.gl DNS名称:youtu.be DNS名称:youtube.com
DNS名称:youtubeeducation.com]

[9]:ObjectId:2.5.29.14严重性= false SubjectKeyIdentifier [KeyIdentifier [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 30A 30 31 1F .......... ZZZZ01.030: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 .. 0070:08 84 2C 18 C6 A8 9C 57 5F 2B CC 9B 4F 7A 72 87 ....... W _ + .. Ozr。0080:C1 19 BC 0B 98 8B 09 1E 1D B1 5A BB 34 B6 95 1E .......... Z.4 ... 0090:B9 37 27 5C C4 73 DB AE 68 B7 B1 F9 E7 4D BB 75 .7 '.s.h .... Mu 00A0:0B CE 16 75 B0 48 F2 39 AC DB 7C 68 C2 13 16 82 ... uH9 ... h .... 00B0:D2 E8 A8 F2 C1 D4 45 69 2C 8E D0 D4 FB 3D 74 7D ...... Ei,。= t.00C0:02 CF 7C D6 17 64 63 9A E6 3B 8D F4 93 62 58 56 .... dc .. ; ... bXV 00D0:49 F8 0D 28 15 BC C5 B1 0F 66 1C 19 DF 83 A5 94 I ..(..... f ...... 00E0:1C 2F 6A E1 A2 31 A1 23 C8 07 F8 09 BF A1 9A E4 ./j..1。#........ 00F0:EB E8 1A 7C 9D 89 CF 22 8A 4F 64 CC 8F D7 20 BD .......”。奇怪...

]

从证书例外9:[1]和[2]中可以看出,证书可以使用OSCP URL和CRL URL。两者都在中间证书中,但在根证书中也不存在,这是合理的,因为它们不需要它们。

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

线程“主”中的异常java.lang.RuntimeException:java.security.cert.CertPathValidatorException:证书未在test_data.ImportAndTestCert.java:157处的test_data.ImportAndTestCert.java:157处指定OCSP响应程序:ImportAndTestCert.java: 72)由以下原因引起:java.security.cert.CertPathValidatorException:证书未在sun.security.provider.certpath.PKIXCertPathValidator.validate处的sun.security.provider.certpath.PKIXMasterCertPathValidator.validate(PKIXMasterCertPathValidator.java:135)上指定OCSP响应者(java.sun.security.provider.certpath.PKIXCertPathValidator.validate(PKIXCertPathValidator.java:140)上的sun.security.provider.certpath.PKIXCertPathValidator.engineValidate(PKIXCertPathValidator.java:79)上的java。在test_data.ImportAndTestCert.isCertChainValid(ImportAndTestCert.java:126)的security.cert.CertPathValidator.validate(CertPathValidator.java:292)... 1另外

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

线程“主”中的异常java.lang.RuntimeException:java.security.cert.CertPathValidatorException:无法确定test_data.ImportAndTestCert.main(ImportAndTestCert.java:72处的test_data.ImportAndTestCert.isCertChainValid(ImportAndTestCert.java:157)的吊销状态)由以下原因引起:java.security.cert.CertPathValidatorException:无法在sun.security.provider.certpath.PKIXCertPathValidator.validate(PKIXCertPathValidator)处sun.security.provider.certpath.PKIXMasterCertPathValidator.validate(PKIXMasterCertPathValidator.java:135)处确定吊销状态.java:219)位于sun.security.provider.certpath.PKIXCertPathValidator.validate(PKIXCertPathValidator.java:140)位于java.security.cert处sun.security.provider.certpath.PKIXCertPathValidator.engineValidate(PKIXCertPathValidator.java:79)处。CertPathValidator.validate(CertPathValidator.java:292)at test_data.ImportAndTestCert.isCertChainValid(ImportAndTestCert.java:126)...还有1个

我在这里想念什么吗?

感谢您的帮助。

Var*_*val 5

我发现了问题。

麻烦的根源在于certpath中存在根证书。

根证书不包含CRL和OSCP链接。继续更新存储库是Trusted Certificate Repository或TrustStore的工作。

由于根证书不包含CRL和OSCP链接,因此出现诸如

线程“主”中的异常java.lang.RuntimeException:java.security.cert.CertPathValidatorException:无法确定位于以下位置的吊销状态

线程“主”中的异常java.lang.RuntimeException:java.security.cert.CertPathValidatorException:证书未在以下位置指定OCSP响应程序

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