如何使用JAVA检查X509证书链的吊销状态? [英] How to check revocation status of X509Certificate chain using JAVA?

查看:156
本文介绍了如何使用JAVA检查X509证书链的吊销状态?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一连串的X509证书,以用户证书开头,以受信任的CA证书结尾。对于测试,我正在尝试使用Google证书。



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



我正在使用以下代码:

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

try {

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

CertPath certPath = certificateFactory.generateCertPath(certificateList);

CertPathValidator验证程序= CertPathValidator.getInstance( PKIX);

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

PKIXParameters参数=新的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)validateator.validate(certPath,params);
返回true;
} catch(CertificateException e){
抛出新的RuntimeException(e);

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

} catch(KeyStoreException e){
抛出新的RuntimeException(e);

} catch(IOException e){
抛出新的RuntimeException(e);

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

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

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

  public static void main(String args [])引发异常{

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 =新的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
View,ST = California,C = US签名算法:SHA256withRSA,OID =
1.2.840.113549.1.1.11



密钥:Sun EC公共密钥,256位公共x坐标:
46177506158937302063723158048612066903199153823785912505310712817097913459047
公共y坐标:
113809014154880901150321029617294838083005712679903474974082163637608868220 N2bP-b参数:xpP1:P256:256 .62 prime256v1]
(1.2.840.10045.3.1.7)有效期:[自:IST 2016年6月16日星期四14:07:32,
收件人:IST 2016年9月8日星期三13:59:00]发行者: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 [[访问sMethod:caIssuers
访问位置:URIName: http://pki.google.com/GIAG2.crt

访问方法:ocsp访问位置: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:[< br>
CA:false PathLen:未定义]



[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 DNSName:* .google.ca DNSName:* .google.cl DNSName:* .google.co .in DNSName:* .google.co.jp DNSName:
* .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 DNSNam e:* .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

DNS名称:www.goo.gl DNS名称:youtu.be DNS名称:youtube.com

DNSName :youtubeeducation.com]



[9]:ObjectId:2.5.29.14 Criticality = 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 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..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 .......。Od ...。



]


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



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


线程 main中的异常java.lang.RuntimeException:
java.security.cert.CertPathValidatorException:证书未在

中指定OCSP响应者test_data.ImportAndTestCert.isCertChainVali d(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); ,它是给我以下错误:


线程 main中的异常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)
at
sun.security.provider.certpath.PKIXCertPathValidator.validate(PKIXCertPathValidator.java:140)
at
sun.security.provider.certpath.PKIXCertPathValidator.engineValidate(PKIXCertPathValidator.java:79)

java.security.cert.CertPathV alidator.validate(CertPathValidator.java:292)
at
test_data.ImportAndTestCert.isCertChainValid(ImportAndTestCert.java:126)
... 1


我在这里错过了什么吗?



感谢您的帮助。

解决方案

我发现了问题。



在证书路径中存在根证书会造成所有麻烦。 / p>

根证书不包含CRL和OSCP链接。



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


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



线程主中的异常java.lang.RuntimeException:
java.security.cert.CertPathValidatorException:证书未在$ p
中指定OCSP响应者


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


I am having a chain of X509Certificates starting with user certificate and ending with trusted CA certificate. For the test, I am experimenting with Google certificates.

I want to check the revocation status of every certificate in Certificate chain.

I am using following code:

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);
    }
}

This is how I get list of certificates:

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 are the end, intermediate and root certificates respectively obtained using the export option in browser.

CertVal is a class made by me that will import certificate from file and its method will return certificate object. It is working fine and end certificate is nicely printed as shown below:

[ [ Version: V3 Subject: CN=*.google.com, O=Google Inc, L=Mountain View, ST=California, C=US Signature Algorithm: SHA256withRSA, OID = 1.2.840.113549.1.1.11

Key: Sun EC public key, 256 bits public x coord: 46177506158937302063723158048612066903199153823785912505310712817097913459047 public y coord: 113809014154880901150321029617294838083005712679903474974082163637608868220331 parameters: secp256r1 [NIST P-256, X9.62 prime256v1] (1.2.840.10045.3.1.7) Validity: [From: Thu Jun 16 14:07:32 IST 2016, To: Thu Sep 08 13:59:00 IST 2016] Issuer: CN=Google Internet Authority G2, O=Google Inc, C=US SerialNumber: [
51e47ed1 28a4436e]

Certificate Extensions: 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: URIName: 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......h.v....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 DNSName: *.google.ca DNSName: *.google.cl DNSName: *.google.co.in DNSName: *.google.co.jp DNSName: *.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 DNSName: googlecommerce.com DNSName: urchin.com
DNSName: www.goo.gl DNSName: youtu.be DNSName: youtube.com
DNSName: youtubeeducation.com ]

[9]: ObjectId: 2.5.29.14 Criticality=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
.`.. ] ]

] Algorithm: [SHA256withRSA] Signature: 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.. 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....M.u 00A0: 0B CE 16 75 B0 48 F2 39 AC DB 7C 68 C2 13 16 82 ...u.H.9...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 .......".Od... .

]

As it is seen in Certificate Exceptions 9:[1] and [2], OSCP URL and CRL URL both are available with certificate. Both these things are there in intermediate certificate too but they are not there in root certificate which is justifiable since they are not needed with them.

My problem is when I run above program, it gives me following error.

Exception in thread "main" java.lang.RuntimeException: java.security.cert.CertPathValidatorException: Certificate does not specify OCSP responder at test_data.ImportAndTestCert.isCertChainValid(ImportAndTestCert.java:157) at test_data.ImportAndTestCert.main(ImportAndTestCert.java:72) Caused by: java.security.cert.CertPathValidatorException: Certificate does not specify OCSP responder at sun.security.provider.certpath.PKIXMasterCertPathValidator.validate(PKIXMasterCertPathValidator.java:135) at sun.security.provider.certpath.PKIXCertPathValidator.validate(PKIXCertPathValidator.java:219) at sun.security.provider.certpath.PKIXCertPathValidator.validate(PKIXCertPathValidator.java:140) at sun.security.provider.certpath.PKIXCertPathValidator.engineValidate(PKIXCertPathValidator.java:79) at java.security.cert.CertPathValidator.validate(CertPathValidator.java:292) at test_data.ImportAndTestCert.isCertChainValid(ImportAndTestCert.java:126) ... 1 more

If I comment Security.setProperty("ocsp.enable", "true");, it is giving me following error:

Exception in thread "main" java.lang.RuntimeException: java.security.cert.CertPathValidatorException: Could not determine revocation status at test_data.ImportAndTestCert.isCertChainValid(ImportAndTestCert.java:157) at test_data.ImportAndTestCert.main(ImportAndTestCert.java:72) Caused by: java.security.cert.CertPathValidatorException: Could not determine revocation status at sun.security.provider.certpath.PKIXMasterCertPathValidator.validate(PKIXMasterCertPathValidator.java:135) at sun.security.provider.certpath.PKIXCertPathValidator.validate(PKIXCertPathValidator.java:219) at sun.security.provider.certpath.PKIXCertPathValidator.validate(PKIXCertPathValidator.java:140) at sun.security.provider.certpath.PKIXCertPathValidator.engineValidate(PKIXCertPathValidator.java:79) at java.security.cert.CertPathValidator.validate(CertPathValidator.java:292) at test_data.ImportAndTestCert.isCertChainValid(ImportAndTestCert.java:126) ... 1 more

Am I missing something here?

Thanks for helping.

解决方案

I found the problem.

It was the presence of root certificate in certpath that was creating all the trouble.

Root certificates don't contain CRL and OSCP links. It is the job of Trusted Certificate Repository or TrustStore to keep updating the repository.

Since root certificate don't contain CRL and OSCP links, it was giving errors like

Exception in thread "main" java.lang.RuntimeException: java.security.cert.CertPathValidatorException: Could not determine revocation status at

and

Exception in thread "main" java.lang.RuntimeException: java.security.cert.CertPathValidatorException: Certificate does not specify OCSP responder at

In short, to check for revocation status of certificates in a certificate chain, root certificate needs to be excluded. Validator algorithm can determine whether last intermediate certificate is signed by root CA or not.

这篇关于如何使用JAVA检查X509证书链的吊销状态?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆