【发布时间】:2019-02-11 03:22:48
【问题描述】:
我有一个 Java 应用程序,它使用智能卡中的证书来执行 TLS/SSL 客户端身份验证。 智能卡有 2 个证书,一个用于签名,另一个用于身份验证。我就是这样做的:
// loading windows-my store
KeyStore windowsMyKeyStore = KeyStore.getInstance("Windows-MY", "SunMSCAPI");
windowsMyKeyStore.load(null, null);
// loading keymanager
KeyManagerFactory keyManagerFactory = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm());
keyManagerFactory.init(windowsMyKeyStore, null);
// building truststore
TrustManager[] trustAllManager = new TrustManager[]{new X509TrustManager() {
public X509Certificate[] getAcceptedIssuers() {
return new X509Certificate[0];
}
public void checkClientTrusted(X509Certificate[] certs, String authType) {
}
public void checkServerTrusted(X509Certificate[] certs, String authType) {
}
}};
SSLContext sslContext = SSLContext.getInstance("TLS");
sslContext.init(keyManagerFactory.getKeyManagers(), trustAllManager, new SecureRandom());
SSLConnectionSocketFactory sslConnectionSocketFactory = new SSLConnectionSocketFactory(sslContext,
new String[]{"TLSv1.2", "TLSv1.1"},
null,
SSLConnectionSocketFactory.getDefaultHostnameVerifier());
HttpClient httpClient = HttpClients.custom()
.setSSLSocketFactory(sslConnectionSocketFactory)
.build();
HttpGet get = new HttpGet(...);
出现问题是因为 Java 选择了与来自服务器的 CertificateRequest 匹配的 第一个 证书(错误的),正如-Djavax.net.debug=all 时的这段摘录中所见:
*** ServerHelloDone
[read] MD5 and SHA1 hashes: len = 4
0000: 0E 00 00 00 ....
matching alias: <<alias for SIGNING certificate>>
matching alias: <<alias for AUTHENTICATION certificate>>
*** Certificate chain
chain [0] = [
<< SIGNING certificate >>
]
是否可以配置 Java 使其使用正确的证书?
【问题讨论】:
-
要配置 Java,您可以编写自己的
KeyManager,它主要包含标准的,但可以根据需要调整chooseClientAlias(以及可选的getClientAliases)。使用 HttpClient,您还可以使用org.apache.http.ssl.SSLContextBuilder(在旧版本中为..http.conn.ssl..),它提供了一个使用PrivateKeyStrategy的包装器(KeyManagerDelegate),您可以提供它来控制别名选择。 -
@dave_thompson_085 谢谢!我尝试了很多东西!我什至最终清除了“Windows-my store”(使用 certutil.exe)并只安装了正确的证书。能否请您提出您的答案,以便我接受,然后我将对其进行编辑以添加代码。
-
我没有做足够的工作来回答,只是一个提示。如果您提出了一个好的答案,请继续;明确允许自我回答(尽管您可能需要等待接受 IIRC),或者如果您愿意,可以将其设为社区。span>
标签: java windows ssl smartcard client-certificates