【问题标题】:Java ClientAuth SSL connection failsJava ClientAuth SSL 连接失败
【发布时间】:2016-08-03 21:33:15
【问题描述】:

我有一个基于 Java 的客户端,它通过 Tomcat 8 与我的 Java 服务器通信。我需要让 ClientAuth SSL 在客户端和服务器之间工作。我有 2 个不同的问题,具体取决于我将 Tomcat 配置为使用 Http11NioProtocol 进行 SSL 还是使用本机 APR (openssl) 进行 SSL。我需要 Tomcat 配置才能工作。我尝试了两种方法来缩小问题范围。

客户端代码如下。我转而使用自定义 X509ExtendedTrustManager (ServerTrustManager) 和 X509ExtendedKeyManager (ClientAuthKeyManager) 类,以确保提供正确的数据并帮助调试。

ServerTrustManager serverTm = new ServerTrustManager(getCaCertificates());
TrustManager [] trustManagers = new TrustManager[] { serverTm };
                ClientAuthKeyManager mykm = 
                        new ClientAuthKeyManager(getSessionContext().getProductAgentCertificate(), getSessionContext());
KeyManager[] keyManagers = new KeyManager[] { mykm };

SSLContext sslContext = SSLContexts.createDefault();
sslContext.init(keyManagers, trustManagers, null);
Client clientHttps = ClientBuilder.newBuilder()
                    .withConfig(getClientConfig())
                    .sslContext(sslContext)
                    .build();

TOMCAT WITH APR (OPENSSL)

Tomcat 8 配置:

<Connector port="8443"  
protocol="org.apache.coyote.http11.Http11AprProtocol"
SSLEnabled="true" 
SSLVerifyClient="require"
SSLCertificateFile="...\dim.magnicomp.com-productserver.crt"
SSLCertificateKeyFile="...\dim.magnicomp.com-productserver.key" 
SSLPassword="..."
SSLCertificateChainFile="...\ca-bundle.crt"
maxThreads="200" 
scheme="https" 
secure="true"/>

问题:我可以为 Apr/OpenSSL 代码启用调试输出/日志记录吗?我在这方面找不到任何来自谷歌的结果。

使用这个 Tomcat 配置,我的 Java 客户端无法连接(来自客户端的 ssl 调试):

... snip ...
*** CertificateVerify
Signature Algorithm SHA512withRSA
main, WRITE: TLSv1.2 Handshake, length = 264
main, WRITE: TLSv1.2 Change Cipher Spec, length = 1
main, handling exception: java.net.SocketException: Software caused connection abort: socket write error
%% Invalidated:  [Session-1, TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384]
main, SEND TLSv1.2 ALERT:  fatal, description = unexpected_message
main, WRITE: TLSv1.2 Alert, length = 2
main, Exception sending alert: java.net.SocketException: Software caused connection abort: socket write error
main, called closeSocket()
17:05:17,709 ERROR JAX-RS ProcessingException for https://dim.magnicomp.com:8443/cabridge/v1/device/configuration - java.net.SocketException: Software caused connection abort: socket write error

使用相同的配置,带有 ClientAuth 证书的“openssl s_client ...”命令可以工作:

# openssl s_client -connect localhost:8443 -CAfile ca-bundle.crt -cert dim.magnicomp.com-productagent.crt -key dim.magnicomp.com-productagent.key
CONNECTED(00000003)
depth=2 CN = MagniComp Root CA
verify return:1
depth=1 DC = com, DC = magnicomp, CN = MagniComp Issuing CA3
verify return:1
depth=0 CN = dim.magnicomp.com
verify return:1
write:errno=113
---
Certificate chain
 0 s:/CN=dim.magnicomp.com
   i:/DC=com/DC=magnicomp/CN=MagniComp Issuing CA3
 1 s:/DC=com/DC=magnicomp/CN=MagniComp Issuing CA3
   i:/CN=MagniComp Root CA
 2 s:/CN=MagniComp Root CA
   i:/CN=MagniComp Root CA
---
... snip ...

TOMCAT WITH Http11NioProtocol

Tomcat 端似乎无法接受 ClientAuth 证书(来自 Tomcat/Apr 的输出):

http-nio-8443-exec-2, fatal error: 46: General SSLEngine problem
sun.security.validator.ValidatorException: PKIX path validation failed: java.security.cert.CertPathValidatorException: signature check failed
%% Invalidated:  [Session-1, TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384]
http-nio-8443-exec-2, SEND TLSv1.2 ALERT:  fatal, description = certificate_unknown

上述 Tomcat 错误来自我的 Java 客户端或“openssl s_connect”:

# openssl s_client -connect localhost:8443 -CAfile ca-bundle.crt -cert dim.magnicomp.com-productagent.crt -key dim.magnicomp.com-productagent.key
CONNECTED(00000003)
depth=2 CN = MagniComp Root CA
verify return:1
depth=1 DC = com, DC = magnicomp, CN = MagniComp Issuing CA3
verify return:1
depth=0 CN = dim.magnicomp.com
verify return:1
6870300:error:14094416:SSL routines:ssl3_read_bytes:sslv3 alert certificate unknown:s3_pkt.c:1472:SSL alert number 46
6870300:error:140790E5:SSL routines:ssl23_write:ssl handshake failure:s23_lib.c:177:
---
Certificate chain
 0 s:/CN=dim.magnicomp.com
   i:/DC=com/DC=magnicomp/CN=MagniComp Issuing CA3
 1 s:/DC=com/DC=magnicomp/CN=MagniComp Issuing CA3
   i:/CN=MagniComp Root CA
---
Server certificate
-----BEGIN CERTIFICATE-----
... snip ...
-----END CERTIFICATE-----
subject=/CN=dim.magnicomp.com
issuer=/DC=com/DC=magnicomp/CN=MagniComp Issuing CA3
---
Acceptable client certificate CA names
/CN=MagniComp Root CA
/DC=com/DC=magnicomp/CN=MagniComp Issuing CA3
Client Certificate Types: RSA sign, DSA sign, ECDSA sign
Requested Signature Algorithms: ECDSA+SHA512:RSA+SHA512:ECDSA+SHA384:RSA+SHA384:ECDSA+SHA256:RSA+SHA256:ECDSA+SHA224:RSA+SHA224:ECDSA+SHA1:RSA+SHA1:DSA+SHA1:RSA+MD5
Shared Requested Signature Algorithms: ECDSA+SHA512:RSA+SHA512:ECDSA+SHA384:RSA+SHA384:ECDSA+SHA256:RSA+SHA256:ECDSA+SHA224:RSA+SHA224:ECDSA+SHA1:RSA+SHA1:DSA+SHA1
Peer signing digest: SHA512
Server Temp Key: ECDH, P-256, 256 bits
---
SSL handshake has read 4528 bytes and written 5835 bytes
---
New, TLSv1/SSLv3, Cipher is ECDHE-RSA-AES256-GCM-SHA384
Server public key is 2048 bit
Secure Renegotiation IS supported
Compression: NONE
Expansion: NONE
No ALPN negotiated
SSL-Session:
    Protocol  : TLSv1.2
    Cipher    : ECDHE-RSA-AES256-GCM-SHA384
    Session-ID: 57102D9B932A1CBBCEFB687A74885A204D3473D8154EBA09D8E073173B18CC17
    Session-ID-ctx:
    Master-Key: 9BDC26F7CD11D05F2EFF07764F280D167E1547306B6626EF9955C97805816A13F7A0ABB9CCC3BF883282998881DDFFB3
    Key-Arg   : None
    PSK identity: None
    PSK identity hint: None
    SRP username: None
    Start Time: 1460678043
    Timeout   : 300 (sec)
    Verify return code: 0 (ok)

Tomcat server.xml:

<Connector 
protocol="org.apache.coyote.http11.Http11NioProtocol" 
SSLEnabled="true" 
clientAuth="true" 
keyAlias="privatekey" 
keyPass="..."
keystoreFile="...\dim.magnicomp.com-productserver.jks" 
keystorePass="..."
keystoreType="JKS"
maxThreads="200" 
port="8443" 
scheme="https"
secure="true" 
truststoreFile="...\cacerts.jks" 
truststorePass="changeit"/>

开发环境 我正在使用 Oracle Java 1.8.65。我已经在 J​​VM 中安装了完整的 JCE 并验证了它的启用。 Agent和服务器是同一个Windows 10系统。

【问题讨论】:

    标签: java tomcat ssl


    【解决方案1】:
    1. 在 APR 环境中,您尚未将 OpenSSL 配置为信任任何证书颁发机构。您需要设置任一

      SSLCACertificatePath
      

      SSLCACertificateFile
      

      请参阅documentation

    2. 在非 APR 情况下,您的信任库不信任客户端证书。如果它是自签名的,则需要将其导入到信任库中,这意味着您应该将 JDK/JRE 信任库复制到本地并导入其中,这样您就不会被下一次 Java 更新所破坏。如果不是自签名的,则需要如上所述导入 CA 的证书。在这两种情况下都必须使用keytool -trustcacerts 选项。

    【讨论】:

    • 是的,APR 配置的 SSLCACertificatePath 正是我所缺少的。我把它与 SSLCertificateChainFile 混淆了,我现在意识到它是用于 SSLCertificateFile 的。谢谢EJP!!!!!!
    猜你喜欢
    • 2013-10-14
    • 1970-01-01
    • 2018-06-22
    • 2013-10-10
    • 2018-12-30
    • 1970-01-01
    • 2011-09-16
    • 2016-01-27
    • 2012-03-13
    相关资源
    最近更新 更多