【问题标题】:Setting a client certificate as a request property in a Java HTTP connection?将客户端证书设置为 Java HTTP 连接中的请求属性?
【发布时间】:2015-03-05 17:08:38
【问题描述】:

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

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

我想在请求中提供给 Web 服务器的客户端证书与设置为我的 JVM 系统属性的证书不同。有没有办法可以设置客户端证书。作为HTTPSURLConnectionImpl 中的请求属性?

【问题讨论】:

  • 在 HTTP 标头中发送它是不够的。它不会安全地识别您。您必须通过 SSL 机制发送它,以便执行与它相关的其他 SSL 步骤,从而提供安全的身份验证。

标签: java url https certificate


【解决方案1】:

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

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

通过配置

您可以将您的客户端密钥和证书添加到您的 JVM KeyStore,当服务器要求您进行客户端 SSL 身份验证时,应该在运行时获取它。 (SSL/TLS 就是为此而设计的:服务器将要求一个由其受信任的授权机构签署的客户端证书,这允许 SSL 引擎选择正确的证书,即使您的 KeyStore 拥有许多证书也是如此)。

通过代码

您可以使用定制的KeyStore/TrustStores 滚动您自己的SSLContext。 这有点复杂(我不会详细说明如何在 Java 中构建 Keystore 实例),但要点在这里:

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 !
}

【讨论】:

  • 有可能但不够,而且客户端证书不是密钥,否则很好回答。
  • 谢谢。滚动我自己的 SSLContext 对我来说是正确的方法,并且具有一定的灵活性。
  • 能否发布并分享您的最终解决方案?
猜你喜欢
  • 1970-01-01
  • 2017-01-24
  • 1970-01-01
  • 2018-11-01
  • 1970-01-01
  • 1970-01-01
  • 2017-01-21
  • 1970-01-01
  • 2017-04-09
相关资源
最近更新 更多