直接通过
HTTPSURLConnectionImpl的请求属性设置SSL“客户证书”是不够的,因为还需要数字签名来证明您拥有证书。SSL已经自动执行所有操作,因此使用该层很有意义。
您有两种方法可以解决您的问题。
通过配置
您可以将客户端密钥和证书添加到JVM KeyStore中,当服务器要求您进行客户端SSL身份验证时,应在运行时将其提取。(SSL /
TLS是为此目的而设计的:服务器将请求由其可信授权机构签名的客户端证书,即使您的KeyStore拥有很多证书,SSL引擎也可以选择正确的证书)。
通过代码
您可以
SSLContext使用定制的
KeyStore/
TrustStores
滚动自己的文件。这有点复杂(我不会详细介绍如何
Keystore在Java中构建实例),但是要点在这里:
public static void main(String[] args) throws Exception {KeyStore clientKeyStore = ... // WhateverKeyStore 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 managersSSLContext 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 SSLSocketFactoryHttpsURLConnection httpsUrlConnection = (HttpsURLConnection) urlConnection;httpsUrlConnection.setSSLSocketFactory(sslSf);// Ready to go !}


