使用X.509证书的Tomcat 9.x.x客户端身份验证

问题描述:

我正在使用Tomcat 9.0.19,并尝试为特定的Web应用程序启用基于X.509证书的客户端身份验证(AKA I& A).

I’m using Tomcat 9.0.19 and trying to enable X.509 cert.-based client authentication (AKA I&A) for a particular Web application.

总而言之,Tomcat适用于通过单向TLS启用了基本I& A的应用程序.在访问具有基于证书的I& A的Web应用程序时,Tomcat在发送Server Hello Done之前似乎并没有要求将客户端证书作为Server Hello消息的一部分,而后来它又通过了身份验证检查:

In summary, the Tomcat works for an application that has basic I&A enabled over one-way TLS. When accessing the Web application that has certificate-based I&A, Tomcat does not seem to request a client certificate as part of the Server Hello message, prior to sending Server Hello Done and it later fails the authentication check:

2020年1月2日13:00:40.371精细[https-jsse-nio-443-exec-10] org.apache.catalina.authenticator.SSLAuthenticator.doAuthenticate查找证书2020年1月2日13:00:40.830精细[https-jsse-nio-443-exec-10] org.apache.catalina.authenticator.SSLAuthenticator.doAuthenticate此请求中不包含证书

02-Jan-2020 13:00:40.371 FINE [https-jsse-nio-443-exec-10] org.apache.catalina.authenticator.SSLAuthenticator.doAuthenticate Looking up certificates 02-Jan-2020 13:00:40.830 FINE [https-jsse-nio-443-exec-10] org.apache.catalina.authenticator.SSLAuthenticator.doAuthenticate No certificates included with this request

在Wireshark中介绍了TLS流,并看到了TLS 1.2握手.交换加密数据后不久,Tomcat会发送加密警报"消息,并且套接字已关闭.尝试从浏览器联系Tomcat,执行GET.浏览器没有提示我选择证书,这似乎也表明Tomcat没有从浏览器请求证书.

Traced the TLS flow in Wireshark and saw the TLS 1.2 handshake. Shortly after encrypted data is exchanged, the Tomcat sends an "Encrypted Alert" message and the socket is closed. Trying to contact the Tomcat from the browser, doing a GET. The browser does not prompt me to select a certificate, which also seems to point to Tomcat not requesting it from the browser.

任何帮助将不胜感激!

更多详细信息:

我们有一组由中间CA颁发的Tomcat和客户端证书,由根CA签名(颁发).双方(客户端和服务器)都已经设置了信任库,以及在其中具有正确的证书/密钥的密钥库.设置Web应用程序以要求证书I& A(web.xml):

We have a set of certificates for the Tomcat and the client, issued by an Intermediate CA, which is signed (issued) by a Root CA. The trust stores have been setup on both sides (client and server) as well as key stores with the right certs/keys in them. The Web application is setup to require certificate I&A (web.xml):

<security-constraint>
    <web-resource-collection>
        <web-resource-name>All by default</web-resource-name>
        <url-pattern>/*</url-pattern>
        <http-method>GET</http-method>
        <http-method>POST</http-method>
    </web-resource-collection>
    <auth-constraint>
        <role-name>OTService</role-name>
    </auth-constraint>

    <user-data-constraint>
        <transport-guarantee>CONFIDENTIAL</transport-guarantee>
    </user-data-constraint>
</security-constraint>

<login-config>
    <auth-method>CLIENT-CERT</auth-method>
    <realm-name>certificate</realm-name>
</login-config>    

在Tomcat-Users.xml中设置了OTService角色以及一个用户帐户:

The OTService role is setup in the Tomcat-Users.xml, along with a single user account:

现在,server.xml中的连接器配置如下:

Now, the Connector in server.xml is configured as follows:

   <Connector port="443" protocol="org.apache.coyote.http11.Http11NioProtocol"
               maxThreads="100" SSLEnabled="true" scheme="https" secure="true">
        <SSLHostConfig>
                                <Certificate certificateKeystoreFile="/apache-tomcat-9.0.19/conf/km/keyStore.jks"
                                certificateKeystorePassword="PASSWORD"
                                certificateKeyAlias="tomcat"
                                type="RSA" />
                                truststoreFile="/apache-tomcat-9.0.19/conf/km/trust_store.jks"
                                truststorePass="PASSWORD"
                                truststoreType="JKS"
                                certificateVerification="required"
                                clientAuth="true"
                                protocols="TLSv1.2"
                </SSLHostConfig>
    </Connector>

有什么想法为什么Tomcat不会请求客户端证书?

Any ideas why Tomcat would not request a client certificate?

如果有:

<Connector ...>
  <SSLHostConfig>
    <Certificate A=1 B=2 C=3 />
    D=4 E=5 F=6
  </SSLHostConfig>
</Connector>

然后,A,B,C是证书对象的属性,而D,E,F不是SSLHostConfig对象的属性-它们是XML content ,这是不同的.需要将属性放在标签中:

then A,B,C are attributes of the Certificate object but D,E,F are NOT attributes of the SSLHostConfig object -- they are XML content which is different. Attributes need to be put IN THE TAG:

<Connector ... >
  <SSLHostConfig certificateVerification="required" truststoreFile=... >
    <Certificate ...keystore... />
  </SSLHostConfig>
</Connector>

并根据需要在初始握手时执行cert-request(对我来说,已在tomcat 9.0.14上进行了测试).

and that does cert-request on the initial handshake as desired (for me, tested on tomcat 9.0.14).