Tomcat 服务器和 HTTP 客户端接受过期的自签名证书

Posted

技术标签:

【中文标题】Tomcat 服务器和 HTTP 客户端接受过期的自签名证书【英文标题】:Tomcat server AND HTTP Client accepting expired self-signed certificate 【发布时间】:2017-10-08 09:00:19 【问题描述】:

我正在编写一个带有相互身份验证的休息客户端和服务器。客户端的密钥库同时充当密钥库和信任库。服务器端的密钥库同时充当密钥库和信任库。

服务器是一个由 Spring boot 启动的嵌入式 Tomcat 服务器。

我正在编写两个测试,其中一个验证服务器拒绝带有过期证书的客户端连接,另一个验证客户端没有连接到带有过期证书的服务器。

我有一个使用 java keytool 创建的信任库和密钥库。它们每个都包含一个各自的自签名证书和关联的密钥。

测试 1

客户端具有与过期证书(在服务器的密钥库中)关联的过期密钥(在客户端密钥库中)。

当我的客户端向服务器发出请求时,服务器会成功处理请求而不是拒绝请求。服务器应该拒绝该请求。

我正在使用这些属性来配置 tomcat 的信任库。我错过了什么吗?

server.ssl.trust-store=truststore location
server.ssl.trust-store-password=password
server.ssl.trust-alias=trust alias
server.ssl.client_auth=NEED

测试 2

服务器具有与过期证书(在客户端的密钥库中)关联的过期密钥(在服务器密钥库中)。

当我的客户端(Apache HTTP 客户端)向服务器发出请求时,请求成功。这是错误的行为。我的解决方法是为解决问题的 SSL 上下文创建一个新的 TrustStrategy。

    return new TrustStrategy() 

        /**
         * Checks to see if certificate has not expired yet.
         * 
         * Always returns false so the trust manager is consulted.
         */
        @Override
        public boolean isTrusted(X509Certificate[] chain, String authType) throws CertificateException
        
            for (X509Certificate certificate : chain)
            
                certificate.checkValidity();
            

            return false;
        

    ;

默认行为不应该是拒绝过期的证书吗? Embedded Tomcat 上的证书信任管理器是什么?如何修改它以拒绝过期的证书?

谢谢!

使用 spring-boot 1.4.0、嵌入式 tomcat 7.0.70、Apache HTTP Client 4.3.6

【问题讨论】:

【参考方案1】:

我发现了问题。

观察到的行为背后的原因是 X509TrustManager 使用 PKIXValidator 来验证客户端和服务器证书。如果验证器想要验证的证书已经存在于信任库中,那么它会自动信任它而不进行任何验证。

我能够通过用我自己的手动检查到期的 TrustManager 包装来启用到期验证。

【讨论】:

以上是关于Tomcat 服务器和 HTTP 客户端接受过期的自签名证书的主要内容,如果未能解决你的问题,请参考以下文章

Http协议以及模拟http请求发送数据

memcached 能接受的 key 的最大长度是多少?

TomcatJPS中常见的tomcat报错错误分析

Tomcat 中带有过期日期的 JSESSIONID Cookie

Nginx搭配Tomcat实现负载均衡

如何让 Apache Tomcat 接受 DELETE 方法