我正在拥有一系列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 View,ST = California,C = US签名算法:SHA256withRSA,OID = 1.2.840.113549.1.1.11
密钥:Sun EC公钥,256位公共x coord: 46177506158937302063723158048612066903199153823785912505310712817097913459047 public y coord: 113809014154880901150321029617294838083005712679903474974082163637608868220331 参数:secp256r1 [NIST P-256,X9.62 prime256v1] (1.2.840.10045.3.1.7)有效期:[来自:2016年6月16日星期四14:07:32, 致:2016年9月8日星期四13:59:00 IST 2016]发行人:CN = Google Internet Authority G2,O = Google Inc,C = US SerialNumber:[
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: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
.` ..]]]算法:[SHA256withRSA]签名:0000:38 89 81 D8 57 DA 3C C7 60 EA BA 6B 08 D4 92 47 8 ... W.&lt;。
..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 ..&#34; C / .S ...... GD \ 0060:EF 16 7A 73 2F 37 CB 39 48 3C F2 87 C5 77 82 A0 ..zs / 7.9H&lt; ... 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&#39; .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 .......&#34; .Od ...。
如证书例外9中所示:[1]和[2],OSCP URL和CRL URL都可以使用证书。这些东西都存在于中间证书中,但它们不存在于根证书中,这是合理的,因为它们不需要它们。
我的问题是,当我在程序上运行时,它会给我以下错误。
线程中的异常&#34; main&#34;了java.lang.RuntimeException: java.security.cert.CertPathValidatorException:证书没有 指定OCSP响应者 test_data.ImportAndTestCert.isCertChainValid(ImportAndTestCert.java:157) 在test_data.ImportAndTestCert.main(ImportAndTestCert.java:72)引起 by: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");
,则会出现以下错误:
线程中的异常&#34; main&#34;了java.lang.RuntimeException: java.security.cert.CertPathValidatorException:无法确定 撤销地位 test_data.ImportAndTestCert.isCertChainValid(ImportAndTestCert.java:157) 在test_data.ImportAndTestCert.main(ImportAndTestCert.java:72)引起 by: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个
我在这里错过了什么吗?
感谢您的帮助。
答案 0 :(得分:3)
我发现了问题。
在certpath中存在根证书造成了所有麻烦。
根证书不包含CRL和OSCP链接。 Trusted Certificate Repository或TrustStore的工作是不断更新存储库。
由于根证书不包含CRL和OSCP链接,因此会出现错误,如
线程中的异常&#34; main&#34;了java.lang.RuntimeException: java.security.cert.CertPathValidatorException:无法确定
的撤销状态
和
线程中的异常&#34; main&#34;了java.lang.RuntimeException: java.security.cert.CertPathValidatorException:证书没有
指定OCSP响应者
简而言之,要检查证书链中证书的撤销状态,需要排除根证书。验证器算法可以确定最后的中间证书是否由根CA签名。