我正在处理一个分布式应用程序中的服务器,该应用程序具有浏览器客户端,并且还参与与第三方的服务器到服务器通信。我的服务器拥有CA签名证书,以便我的客户端可以使用TLS(SSL)通信使用HTTP / S和XMPP(安全)进行连接。这一切都运行良好。
现在我需要安全地连接到第三方服务器。在此通信中,我的服务器充当客户端,我有一个由第三方签署的客户端证书。
问题是当我尝试添加从第三方服务器获取的客户端证书并使用标准系统配置(-Djavax.net.ssl.keyStore = xyz)时,我在SSL的调试日志中收到“没有用于客户端身份验证的X.509证书”错误。
但是当我使用相同的密钥库来自定义SSL上下文时,它可以正常工作。以下是相应的代码。
现在我需要安全地连接到第三方服务器。在此通信中,我的服务器充当客户端,我有一个由第三方签署的客户端证书。
问题是当我尝试添加从第三方服务器获取的客户端证书并使用标准系统配置(-Djavax.net.ssl.keyStore = xyz)时,我在SSL的调试日志中收到“没有用于客户端身份验证的X.509证书”错误。
javax.net.ssl|FINE|01|main|2021-09-15 02:07:40.538 IST|CertificateMessage.java:297|No X.509 certificate for client authentication, use empty Certificate message instead
javax.net.ssl|FINE|01|main|2021-09-15 02:07:40.538 IST|CertificateMessage.java:328|Produced client Certificate handshake message (
"Certificates": <empty list>
)
但是当我使用相同的密钥库来自定义SSL上下文时,它可以正常工作。以下是相应的代码。
String keystorePath = "keystorePath";
String keystorePassword = "changeit";
// Make a KeyStore from the JKS file
KeyStore ks = null;
try {
ks = KeyStore.getInstance("JKS");
} catch (KeyStoreException e) {
e.printStackTrace();
}
try (
FileInputStream fis = new FileInputStream(keystorePath)) {
ks.load(fis, keystorePassword.toCharArray());
}
TrustManagerFactory tmf = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
tmf.init(ks);
// Make a KeyManagerFactory from the KeyStore
KeyManagerFactory kmf = KeyManagerFactory.getInstance("SunX509");
kmf.init(ks, keystorePassword.toCharArray());
// Get hold of the default trust manager
X509TrustManager x509Tm = null;
for (TrustManager tm : tmf.getTrustManagers()) {
if (tm instanceof X509TrustManager) {
x509Tm = (X509TrustManager) tm;
break;
}
}
// Now make an SSL Context with our Key Manager and the default Trust Manager
SSLContext sslContext = SSLContext.getInstance("TLS");
sslContext.init(kmf.getKeyManagers(), null, null);
return okHttpClient.newBuilder()
.sslSocketFactory(sslContext.getSocketFactory(), x509Tm)
.connectTimeout(10000, TimeUnit.MILLISECONDS)
.readTimeout(10000, TimeUnit.MILLISECONDS)
.build();
我希望只使用标准系统配置来管理密钥库,而不是自定义SSL上下文。
javax.net.ssl.keyStorePassword
吗? - erickson