[英]Setting a client certificate as a request property in a Java HTTP connection?
我有一個Java應用程序通過SSL套接字通過一個套接字連接到另一個Java應用程序,因此我的客戶端JVM已經設置了-Djavax.net.ssl.keyStore
和-Djavax.net.ssl.trustStore
屬性。
此應用程序需要向需要客戶端身份驗證的Web服務器發出一些HTTP請求。 我可以使用Java中的URLConnection
打開連接,該連接返回HTTPSURLConnectionImpl
。
我要在請求中提供給Web服務器的客戶端證書與設置為我的JVM系統屬性的客戶端證書不同。 有沒有一種方法可以設置客戶端證書。 作為HTTPSURLConnectionImpl
的請求屬性?
直接通過HTTPSURLConnectionImpl
的請求屬性設置SSL“客戶端證書”是不夠的,因為還需要數字簽名來證明您擁有證書。 SSL已經自動執行所有操作,因此使用該層很有意義。
您有兩種方法可以解決您的問題。
您可以將客戶端密鑰和證書添加到JVM KeyStore中,當服務器要求您進行客戶端SSL身份驗證時,應該在運行時將其提取。 (SSL / TLS是為此目的而設計的:服務器將請求由其可信授權機構簽名的客戶端證書,即使您的KeyStore擁有很多證書,SSL引擎也可以選擇正確的證書)。
您可以使用定制的KeyStore
/ TrustStore
滾動自己的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 !
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.