将客户端证书设置为Java HTTP连接中的请求属性? [英] Setting a client certificate as a request property in a Java HTTP conneciton?

查看:322
本文介绍了将客户端证书设置为Java HTTP连接中的请求属性?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个Java应用程序通过带有SSL的套接字连接到另一个Java应用程序,所以我的客户端JVM已经有 -Djavax.net.ssl.keyStore -Djavax.net.ssl.trustStore 属性集。

I have a Java application that connects to another Java app through a socket with SSL, so my client JVM already has the -Djavax.net.ssl.keyStore and -Djavax.net.ssl.trustStore properties set.

此应用程序需要向Web服务器发出一些HTTP请求需要客户端身份验证。我可以使用Java中的 URLConnection 打开连接,返回 HTTPSURLConnectionImpl

This application needs to make some HTTP requests to a web server that requires client authentication. I can open the connection by using a URLConnection in Java which returns an HTTPSURLConnectionImpl.

我要在Web服务器上显示的客户端证书与设置为JVM系统属性的客户端证书不同。有没有办法我可以设置客户端证书。作为 HTTPSURLConnectionImpl

The client certificate I want to present to the web server in the request is different than the one set as my JVM system property. Is there a way I can set a client cert. as a request property in the HTTPSURLConnectionImpl ?

推荐答案

设置SSL的请求属性客户端证书不能通过 HTTPSURLConnectionImpl 的请求属性直接获得,因为还需要数字签名来证明您拥有证书。 SSL已经自动完成所有操作,因此使用该图层是有意义的。

Setting a SSL "client certificate" is not adequate directly through HTTPSURLConnectionImpl's request properties, because a digital signature is also required to prove you own the certificate. SSL already does all that automatically, so to makes sense to use that layer.

您有两种方法可以解决您的问题。

You have two ways to solve your issue going forward.

您可以将客户端密钥和证书添加到JVM KeyStore,当服务器请求您的客户端SSL认证。 (SSL / TLS设计用于:服务器将要求一个由其受信任的机构签署的客户端证书,这允许SSL引擎选择正确的证书,即使您的KeyStore拥有多个)。

You can add you client key and certificate to your JVM KeyStore, it should be picked up at Runtime when the server asks for your client-side SSL authentication. (SSL/TLS is designed for that : the server will ask for a client certificate that is signed by it's trusted authority, which allows the SSL Engine to choose the right certificate, even when your KeyStore holds many).

您可以使用自定义 SSLContext c $ c> KeyStore / TrustStore
这是一个有点复杂(我不会详细说明如何在Java中创建 Keystore 实例),但它的要点在这里:

You can roll you own SSLContext using custom made KeyStore/TrustStores. This is a bit complex (I won't elaborate on how to build Keystore instances in Java), but the gist of it is here :

public static void main(String[] args) throws Exception {

KeyStore clientKeyStore = ... // Whatever
KeyStore clientTrustStore = ... // Whatever you need to load

// We build the KeyManager (SSL client credentials we can send)
KeyManagerFactory keyFactory = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm());
keyFactory.init(clientKeyStore, "password".toCharArray());
KeyManager[] km = keyFactory.getKeyManagers();

// We build the TrustManager (Server certificates we trust)
TrustManagerFactory trustFactory = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
trustFactory.init(clientTrustStore);
TrustManager[] tm = trustFactory.getTrustManagers();

// We build a SSLContext with both our trust/key managers
SSLContext sslContext = SSLContext.getInstance("TLS");
sslContext.init(km, tm, null);
SSLSocketFactory sslSf = sslContext.getSocketFactory();

// We prepare a URLConnection 
URL url = new URL("https://www.google.com");
URLConnection urlConnection = url.openConnection();
// Before actually opening the sockets, we affect the SSLSocketFactory
HttpsURLConnection httpsUrlConnection = (HttpsURLConnection) urlConnection;
httpsUrlConnection.setSSLSocketFactory(sslSf);

// Ready to go !
}

这篇关于将客户端证书设置为Java HTTP连接中的请求属性?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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