通过HTTPS / SSL的Java客户端证书 [英] Java client certificates over HTTPS/SSL

查看:168
本文介绍了通过HTTPS / SSL的Java客户端证书的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用Java 6,并尝试使用客户端证书针对远程服务器创建 HttpsURLConnection

服务器正在使用自签名根证书,并要求提供受密码保护的客户端证书。我已将服务器根证书和客户端证书添加到我在 /System/Library/Frameworks/JavaVM.framework/Versions/1.6.0/Home/lib/security/中找到的默认java密钥库中cacerts (OSX 10.5)。
密钥库文件的名称似乎暗示客户端证书不应该进入那里?

I am using Java 6 and am trying to create an HttpsURLConnection against a remote server, using a client certificate.
The server is using an selfsigned root certificate, and requires that a password-protected client certificate is presented. I've added the server root certificate and the client certificate to a default java keystore which I found in /System/Library/Frameworks/JavaVM.framework/Versions/1.6.0/Home/lib/security/cacerts (OSX 10.5). The name of the keystore file seems to suggest that the client certificate is not supposed to go in there?

无论如何,将根证书添加到此商店已解决臭名昭着的 javax.net.ssl.SSLHandshakeException:sun.security.validator.ValidatorException:PKIX路径构建失败'问题。

Anyway, adding the root certificate to this store solved the infamous javax.net.ssl.SSLHandshakeException: sun.security.validator.ValidatorException: PKIX path building failed' problem.

但是,我现在仍然不知道如何使用客户端证书。我尝试了两种方法,但没有让我到任何地方。

首先,首选,尝试:

However, I'm now stuck on how to use the client certificate. I've tried two approaches and neither gets me anywhere.
First, and preferred, try:

SSLSocketFactory sslsocketfactory = (SSLSocketFactory) SSLSocketFactory.getDefault();
URL url = new URL("https://somehost.dk:3049");
HttpsURLConnection conn = (HttpsURLConnection)url.openConnection();
conn.setSSLSocketFactory(sslsocketfactory);
InputStream inputstream = conn.getInputStream();
// The last line fails, and gives:
// javax.net.ssl.SSLHandshakeException: Received fatal alert: handshake_failure

我试过跳过HttpsURLConnection类(不太理想,因为我想与服务器讨论HTTP),而是这样做:

I've tried skipping the HttpsURLConnection class (not ideal since I want to talk HTTP with the server), and do this instead:

SSLSocketFactory sslsocketfactory = (SSLSocketFactory) SSLSocketFactory.getDefault();
SSLSocket sslsocket = (SSLSocket) sslsocketfactory.createSocket("somehost.dk", 3049);
InputStream inputstream = sslsocket.getInputStream();
// do anything with the inputstream results in:
// java.net.SocketTimeoutException: Read timed out

我甚至不确定客户证书是否存在问题。

I am not even sure that the client certificate is the problem here.

推荐答案

终于解决了它)。得到了一个强烈的暗示这里(Gandalfs的回答也有点触及)。丢失的链接(大部分)是下面的第一个参数,在某种程度上我忽略了密钥库和信任库之间的区别。

Finally solved it ;). Got a strong hint here (Gandalfs answer touched a bit on it as well). The missing links was (mostly) the first of the parameters below, and to some extent that I overlooked the difference between keystores and truststores.

自签名服务器证书必须导入信任库:

The self-signed server certificate must be imported into a truststore:


keytool -import -alias gridserver -file gridserver.crt -storepass $ PASS -keystore gridserver.keystore

keytool -import -alias gridserver -file gridserver.crt -storepass $PASS -keystore gridserver.keystore

需要设置这些属性(在命令行或代码中):

These properties need to be set (either on the commandline, or in code):

-Djavax.net.ssl.keyStoreType=pkcs12
-Djavax.net.ssl.trustStoreType=jks
-Djavax.net.ssl.keyStore=clientcertificate.p12
-Djavax.net.ssl.trustStore=gridserver.keystore
-Djavax.net.debug=ssl # very verbose debug
-Djavax.net.ssl.keyStorePassword=$PASS
-Djavax.net.ssl.trustStorePassword=$PASS

工作示例代码:

SSLSocketFactory sslsocketfactory = (SSLSocketFactory) SSLSocketFactory.getDefault();
URL url = new URL("https://gridserver:3049/cgi-bin/ls.py");
HttpsURLConnection conn = (HttpsURLConnection)url.openConnection();
conn.setSSLSocketFactory(sslsocketfactory);
InputStream inputstream = conn.getInputStream();
InputStreamReader inputstreamreader = new InputStreamReader(inputstream);
BufferedReader bufferedreader = new BufferedReader(inputstreamreader);

String string = null;
while ((string = bufferedreader.readLine()) != null) {
    System.out.println("Received " + string);
}

这篇关于通过HTTPS / SSL的Java客户端证书的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆