过期证书上的Java trustmanager行为

Cra*_*lus 13 java security authentication ssl tomcat

如果证书已过期,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


*******************************************
Run Code Online (Sandbox Code Playgroud)

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

TrustManagerFactory tmf = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
Run Code Online (Sandbox Code Playgroud)

并加载过期的证书).
我期待连接失败.
相反,连接成功.
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]

]
Run Code Online (Sandbox Code Playgroud)

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

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

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

void checkServerTrusted(X509Certificate[] chain,String authType)
                                throws CertificateException  
Run Code Online (Sandbox Code Playgroud)

给定对等方提供的部分或完整证书链,构建到受信任根的证书路径,如果可以验证则返回,并且基于身份验证类型对服务器SSL身份验证进行信任.身份验证类型是密钥交换算法的一部分.密码套件表示为字符串,例如"RSA","DHE_DSS".注意:对于某些可导出的密码套件,密钥交换算法在握手期间的运行时确定.例如,对于TLS_RSA_EXPORT_WITH_RC4_40_MD5的authType的应该是RSA_EXPORT当临时的RSA密钥用于密钥交换,而当从服务器证书的密钥使用RSA.检查区分大小写.

谢谢

Mat*_*ons 6

在重写时我自己也遇到过类似的问题checkServerTrusted.

事实证明,如果你需要检查过期,你可以调用X509Certificate.checkValidity()它,它将抛出CertificateExpiredException或CertificateNotYetValidException.这两个都扩展了CertificateException,因此可以愉快地抛出它们checkServerTrusted.

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


Paŭ*_*ann 4

我没有尝试您的示例,但我现在必须定期重新生成我的服务器证书(对于我们的开发服务器),因为它们的证书的有效期很短。

在我们的例子中,客户端在信任库中没有服务器证书本身,而只有我们的 CA 的证书(具有更长的有效期),当客户端尝试连接到服务器时,双方都会收到 SSLException(可能会被包装)在你的情况的另一个例外)。

我猜信任管理器会假设“如果你给我信任的过期证书,我就会这么做”。请尝试我们的方法(它还可以节省您每次服务器证书过期时更新客户端的时间)。

  • 然后 PKIXValidator 查找证书链中是否出现可信证书,如果是,它只获取之前的证书并将它们交给 CertPathValidator 进行检查,CertPathValidator 又委托给 CertPathValidatorSpi 实现来执行实际的加密检查(我希望)。但在此过程中似乎从未完成对根受信任证书过期的检查。 (2认同)