4

这个问题也发布在TLS client authentication failed when using SunMSCAPI but has not found an answer。

我有一个在 Windows Win2008R2 客户端上运行的 Java6 应用程序,该客户端连接到需要客户端证书的服务器。Java 应用程序需要使用本地 Windows 存储,即 Windows-Root 和 Windows-My,并使用 SunMSCAPI 提供程序。Windows 证书管理控制台报告客户端证书和签署它的 CA 证书都是正确的,并且已为所有目的启用。

服务器验证完全按预期工作,但是当客户端抛出 SSLException 抱怨私钥不是 RSA 私钥时,客户端身份验证失败。但是,当使用 Java 默认提供程序,并且从 JKS 密钥库中获取相同的客户端证书时,即不使用 SunMSCAPI 和 Windows 存储,客户端身份验证按预期工作并且 SSL 连接成功。

执行时,应用程序报告它正在使用 SunMSCAPI 提供程序,并且能够打印正确的客户端证书以及有关其 RSAPrivateKey 的信息。跟踪表明客户端异常发生在服务器“Hello Done”之后,因为它正在准备对服务器证书请求的响应。

客户端密钥库部分的相关代码位是:

SSLContext sslContext = SSLContext.getInstance("TLS");
KeyManagerFactory kFac = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm());
Provider pvdr = new sun.security.mscapi.SunMSCAPI();  
Security.insertProviderAt(pvdr,1);
KeyStore kStore = KeyStore.getInstance("Windows-MY",pvdr);
kStore.load(null,null);
kFac.init(kstore,null);
sslContext.init(kFac.getKeyManagers(), <a trust factory>.getTrustManagers(), new java.security.SecureRandom());
SSLSocketFactory sockFactory = SSLSocketFactory(sslContext);
SSLSocket sslSock = (SSLSocket)sockFactory.createSocket(<some destination host>, <some destination port>);
BufferedInputStream bInStr = new BufferedInputStream(sslSock.getInputStream());
bInStr.read(<the read arguments>);   <<< exception thrown in here

任何指示或建议将不胜感激!

4

1 回答 1

2

您的链接中显示的堆栈跟踪显示问题出在 RSA 的 JSSL 提供程序上。特别是对于这种情况,您应该使用 Sun/Oracle 的 JSSE 提供程序。无论如何,它是默认的。

称它为

SSLContext sslContext = SSLContext.getInstance("TLS", "SunJSSE");
于 2012-10-27T01:28:55.857 回答