将SSL用于远程Docker主机和自签名CA的Java客户端身份验证时出错,

时间:2018-08-21 22:28:56

标签: java docker ssl

设置
我和我的团队正在建立应用程序工作流管理的框架。我们正在RHEL 7机器上运行的Apache Servicemix中使用Java OSGi组件。我们希望该框架能够使用安装在远程主机上的Docker。我有一个Docker主机,该主机配置为允许外部客户端通过Docker documentation中概述的HTTPS发出命令,其中涉及一个自签名CA。正确的CA证书(ca.pem),客户端证书(cert.pem)和客户端密钥(key.pem)都在客户端计算机上,以允许我们的框架使用Spotify docker-client API。

CA证书已导入到客户端计算机上的JRE信任库(<JAVA_HOME>/lib/security/cacerts)中。

问题
当我们的框架启动时,我们有一个类初始化Docker客户端,并尝试从远程Docker主机获取图像的JSON响应。服务器通过身份验证后,请求 失败,并出现SSLHandshakeException: Received fatal alert: bad_certificate错误(请参见下面的堆栈跟踪)。

Caused by: javax.net.ssl.SSLHandshakeException: Received fatal alert: bad_certificate
at sun.security.ssl.Alerts.getSSLException(Alerts.java:192)[:1.8.0_131]
at sun.security.ssl.Alerts.getSSLException(Alerts.java:154)[:1.8.0_131]
at sun.security.ssl.SSLSocketImpl.recvAlert(SSLSocketImpl.java:2023)[:1.8.0_131]
at sun.security.ssl.SSLSocketImpl.readRecord(SSLSocketImpl.java:1125)[:1.8.0_131]
at sun.security.ssl.SSLSocketImpl.waitForClose(SSLSocketImpl.java:1769)[:1.8.0_131]
at sun.security.ssl.HandshakeOutStream.flush(HandshakeOutStream.java:124)[:1.8.0_131]
at sun.security.ssl.Handshaker.sendChangeCipherSpec(Handshaker.java:1130)[:1.8.0_131]
at sun.security.ssl.ClientHandshaker.sendChangeCipherAndFinish(ClientHandshaker.java:1216)[:1.8.0_131]
at sun.security.ssl.ClientHandshaker.serverHelloDone(ClientHandshaker.java:1128)[:1.8.0_131]
at sun.security.ssl.ClientHandshaker.processMessage(ClientHandshaker.java:348)[:1.8.0_131]
at sun.security.ssl.Handshaker.processLoop(Handshaker.java:1026)[:1.8.0_131]
at sun.security.ssl.Handshaker.process_record(Handshaker.java:961)[:1.8.0_131]
at sun.security.ssl.SSLSocketImpl.readRecord(SSLSocketImpl.java:1062)[:1.8.0_131]
at sun.security.ssl.SSLSocketImpl.performInitialHandshake(SSLSocketImpl.java:1375)[:1.8.0_131]
at sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1403)[:1.8.0_131]
at sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1387)[:1.8.0_131]
at sun.net.www.protocol.https.HttpsClient.afterConnect(HttpsClient.java:559)[:1.8.0_131]
...
...

在命令行中使用curl以及所需的证书和密钥会从Docker主机产生正确的JSON响应,因此我知道证书都是正确的,并且Docker主机可以使用它们正确地验证客户端。我尝试将客户端证书和密钥导入到JVM的密钥库中,但是错误仍然存​​在。

Spotify Docker客户端根据Docker客户端计算机上的客户端证书,密钥和CA配置自己的SSLContext,以用于其HTTPS请求。我绝对不是专家,但是对我而言,这意味着我不必自己导入客户端证书和密钥。

在配置JVM以与远程Docker主机正确实现双向SSL身份验证时,我是否缺少任何东西?

0 个答案:

没有答案