Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/ssl/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Authentication 使用x.509证书的Tomcat 9.x.x客户端身份验证_Authentication_Ssl_Tomcat_Two Way - Fatal编程技术网

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

Authentication 使用x.509证书的Tomcat 9.x.x客户端身份验证,authentication,ssl,tomcat,two-way,Authentication,Ssl,Tomcat,Two Way,我正在使用Tomcat 9.0.19,并试图为特定的Web应用程序启用基于X.509证书的客户端身份验证,即I&A 总之,Tomcat适用于通过单向TLS启用基本I&A的应用程序。当访问具有基于证书的I&A的Web应用程序时,Tomcat似乎不会在发送服务器Hello Done之前请求客户端证书作为服务器Hello消息的一部分,随后它会失败身份验证检查: 2020年1月2日13:00:40.371 FINE[https-jsse-nio-443-exec-10]org.apache.catali

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

总之,Tomcat适用于通过单向TLS启用基本I&A的应用程序。当访问具有基于证书的I&A的Web应用程序时,Tomcat似乎不会在发送服务器Hello Done之前请求客户端证书作为服务器Hello消息的一部分,随后它会失败身份验证检查:

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

在Wireshark中跟踪TLS流,并看到TLS 1.2握手。加密数据交换后不久,Tomcat发送一条“加密警报”消息,套接字关闭。正在尝试从浏览器中联系Tomcat,执行GET。浏览器不会提示我选择证书,这似乎也指向Tomcat没有从浏览器请求证书

任何帮助都将不胜感激

更多详情:

我们为Tomcat和客户机提供了一组证书,由中间CA颁发,由根CA签发。在客户机和服务器以及密钥存储中都设置了信任存储,其中包含正确的证书/密钥。Web应用程序设置为需要证书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>    
OTService角色在Tomcat-Users.xml中设置,并带有一个单用户帐户:

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

   <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不会请求客户端证书吗?

我发现的第一个问题是Tomcat忽略了信任存储的Connector->SSLHostConfig设置,并使用了JRE默认信任存储。我发现它的方式是让浏览器将协商的TLS会话密钥保存到一个文件Google SSLKEYLOGFILE,然后配置Wireshark使用该文件,捕获浏览器Tomcat会话,然后能够以明文形式查看每条消息

接下来,我发现Tomcat实际上在请求客户端证书,但它发送的已接受根CA列表来自默认的JRE cacerts文件,而不是truststoreFile属性指定的文件。通过将setenv.sh文件添加到Tomcat bin目录,使用Java属性覆盖默认的信任存储位置,可以让Tomcat全面使用不同的文件

现在,我在做生意,浏览器能够完成TLS握手,但是认证和授权步骤失败了。我最终确定,在tomcat_users.xml文件中提供cert.subject字段的正确方法不是CN=OU Client,OU=Control Systems,O=IoTOY,L=Scottsdale,S=AZ,C=US,而是CN=OU Client,OU=Control Systems,O=IoTOY,L=Scottsdale,ST=AZ,C=US。最后,我有双向TLS工作

需要记住的一点是,如果Tomcat上运行的任何东西试图通过TLS连接到另一个使用商业CA证书的系统,它将失败,因为您现在使用的信任库没有商业根CA证书。一种补救方法是复制默认JRE cacerts文件,并将系统特定的CA证书添加到其中,然后从上面提到的setenv.sh文件指向该文件。

如果您有:

<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内容。需要将属性放入标记中:

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

在tomcat 9.0.14上进行测试时,我确实希望在初次握手时发出cert请求。

我认为clientAuth没有真正的值。它是三值的。检查连接器文档。注意:CertificateRequest消息不是ServerHello消息的一部分。正确。它应该是必需的,或者可选的,或者没有。关于clientAuth值的观点很好。将其更改为required,没有任何区别。根据RFC 5246:如果适用于所选密码套件,非匿名服务器可以选择从客户端请求证书。此消息如果发送,将立即跟随ServerKeyExchange消息(如果发送);否则,此消息将跟随服务器的证书消息。我在Wireshark中看到的是,服务器Tomcat发送ServerHello消息,该消息包含:服务器Hello、证书链、服务器密钥交换、服务器Hello Done。因此,我希望在那一点上看到一个cert请求。来自服务器的下一条消息是Change Cipher Spec(更改密码规范)。因此,即使您使用默认的cacerts文件,您仍然获得了CertificateRequest。是的,但我的CA证书DNs列表中有一个错误,因此浏览器没有返回单个客户端/用户证书作为响应。