过期证书上的Java trustmanager行为

时间:2011-03-05 21:22:04

标签: java security authentication tomcat ssl

如果证书已过期,java的TrustManager实现是否会被忽略? 我尝试了以下几点:
  - 使用keytool和参数-startdate "1970/01/01 00:00:00"我创建了一个带有过期证书的P12密钥库 - 我导出了证书:

Keystore type: PKCS12
Keystore provider: SunJSSE

Your keystore contains 1 entry

Alias name: fake
Creation date: 5 ╠ά± 2011
Entry type: PrivateKeyEntry
Certificate chain length: 1
Certificate[1]:
Owner: CN=Malicious, OU=Mal, O=Mal, L=Fake, ST=GR, C=GR
Issuer: CN=Malicious, OU=Mal, O=Mal, L=Fake, ST=GR, C=GR
Serial number: -1c20
Valid from: Thu Jan 01 00:00:00 EET 1970 until: Fri Jan 02 00:00:00 EET 1970
Certificate fingerprints:
         MD5:  A9:BE:3A:3D:45:24:1B:4F:3C:9B:2E:02:E3:57:86:11
         SHA1: 21:9D:E1:04:09:CF:10:58:73:C4:62:3C:46:4C:76:A3:81:56:88:4D
         Signature algorithm name: SHA1withRSA
         Version: 3


*******************************************

我使用此证书作为Tomcat的服务器证书 然后使用我连接到tomcat的apache httpClient,但首先我将过期的证书添加到客户端的信任库(使用TrustManager

TrustManagerFactory tmf = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());

并加载过期的证书。) 我期待连接失败 相反,连接成功 使用System.setProperty("javax.net.debug", "ssl");
我明白了:

***
Found trusted certificate:
[
[
  Version: V3
  Subject: CN=Malicious, OU=Mal, O=Mal, L=Fake, ST=GR, C=GR
  Signature Algorithm: SHA1withRSA, OID = 1.2.840.113549.1.1.5

  Key:  Sun RSA public key, 1024 bits
  modulus: 10350555024148635338735220482157687267055139906998169922552357357346372886164908067983097037540922519808845662295379579697361784480052371935565129553860304254832565723373586277732296157572040989796830623403187557540749531267846797324326299709274902019299
  public exponent: 65537
  Validity: [From: Thu Jan 01 00:00:00 EET 1970,
               To: Fri Jan 02 00:00:00 EET 1970]
  Issuer: CN=Malicious, OU=Mal, O=Mal, L=Fake, ST=GR, C=GR
  SerialNumber: [   -1c20]

]

我看到在TLS握手中,过期的证书是由Tomcat连接器发送的 但客户端(即TrustManager)不拒绝连接 这是默认行为吗? 我是否想以某种方式配置信任管理员来检查到期?

更新
我发现使用的实际TrustManager是X509TrustManagerImpl。这里X509TrustManagerImpl说这个类有一个最小的逻辑。可能我使用错误的TrustManager?

UPDATE2: 从javadoc X509TrustManager,不清楚它是否检查证书过期

void checkServerTrusted(X509Certificate[] chain,String authType)
                                throws CertificateException  
  

鉴于部分或完整   证书链由。提供   peer,建立一个证书路径   受信任的root,如果可以,则返回   验证并受信任服务器   基于SSL的SSL认证   认证类型。认证   type是密钥交换算法   部分密码套房   表示为String,例如   “RSA”,“DHE_DSS”。注意:对于一些人   可出口的密码套件,关键   交换算法确定于   握手期间的运行时间。对于   例如,   TLS_RSA_EXPORT_WITH_RC4_40_MD5 ,.   当a时,authType应为RSA_EXPORT   短暂的RSA密钥用于密钥   交换,和RSA时的关键来自   使用服务器证书。   检查区分大小写。

由于

3 个答案:

答案 0 :(得分:6)

在覆盖checkServerTrusted时,我自己也遇到了类似的问题。

原来,如果你需要检查过期,你可以调用X509Certificate.checkValidity(),它会抛出CertificateExpiredException或CertificateNotYetValidException。这两个都扩展了CertificateException,因此checkServerTrusted可以很高兴地抛出它们。

要解决您的问题,您可以实现一个新的X509TrustManager,它在其构造函数中创建原始实例,将所有方法实现为对原始实例的调用,并为checkValidity中的每个证书添加certs[]调用} checkServerTrusted

答案 1 :(得分:2)

我相信IBM的JSSE会检查到期,而Sun则不会。

答案 2 :(得分:1)

我没有尝试你的例子,但我现在经常需要重新生成我的服务器证书(对于我们的开发服务器),因为他们的证书有效时间很短。

在我们的例子中,客户端在信任库中没有自己的服务器证书,只有我们CA的证书(有效期更长),当客户端尝试连接到服务器时,双方都获得SSLException(在您的情况下可能包含在另一个例外中。)

我想信托经理会假设“如果你给我过期的证书来信任,我就会这样做”。 请尝试我们的方法(每次服务器证书到期时,它还会保存您更新客户端)。