2016-02-06 93 views
5

嘗試實施客戶端身份驗證(使用自簽名ca)。使用HttpClient進行客戶端身份驗證

代碼如下所示:

KeyStore keyStore = KeyStore.getInstance("PKCS12"); 
keyStore.load(new FileInputStream("client.p12"), "changeit".toCharArray()) 

SSLContext sslcontext = SSLContexts.custom() 
      .loadTrustMaterial(null, new TrustSelfSignedStrategy()) //DONT DO THAT, IT'S JUST TO SIMPLIFY THIS EXAMPLE. USE REAL TrustStore WITH REAL SERVER CERTIFICATE IMPORTED. DONT TRUST SELF SIGNED 
      .loadKeyMaterial(keyStore, "changeit".toCharArray()) 
      .build(); 
socketFactory = new SSLConnectionSocketFactory(
      sslcontext, 
      new String[] {"TLSv1.2", "TLSv1.1"}, 
      null, 
      new NoopHostnameVerifier() 
); 
HttpClient httpclient = HttpClients.custom() 
      .setSSLSocketFactory(socketFactory) 
      .build(); 

隨着-Djavax.net.debug=all我可以看到它正確地選擇我的證書,我看到的簽名,我看到的證書請求,並有ECDHClientKeyExchange等,都看起來很好。

但無論如何,我碰到的Nginx以下響應(具有狀態400):

<head><title>400 The SSL certificate error</title></head> 

通知書的,不正確的證書/密鑰nginx的通常會下降,W/O提供純文本響應的任何細節。

client.p12命令行的作品,如:

$ curl -ivk --cert client.p12:changeit https://192.168.1.1 


* Rebuilt URL to: https://192.168.1.1/ 
* Trying 192.168.1.1... 
* Connected to 192.168.1.1 (192.168.1.1) port 443 (#0) 
* WARNING: SSL: Certificate type not set, assuming PKCS#12 format. 
* Client certificate: client-es.certs.my 
* TLS 1.2 connection using TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384 
* Server certificate: server.certs.my 
* Server certificate: ca.my 
> GET/HTTP/1.1 
> Host: 192.168.1.1 
> User-Agent: curl/7.43.0 
> Accept: */* 
> 
< HTTP/1.1 200 OK 

因此,這關鍵是絕對有效的。但爲什麼它不適用於Java?有沒有什麼我在java ssl配置中錯過了?

+0

您的證書是否已導入您的密鑰庫? – STaefi

+0

它直接從'client.p12'加載。我也嘗試將它導入到密鑰庫中,但它不會改變任何東西 –

回答

2

問題是我的客戶端密鑰還包括在鑰匙鏈中籤署證書。不僅是我的客戶證書(這是需要身份驗證),但證書的整個鏈條(當然沒有按鍵,只需證書)

它是:

> Root CA cert -> Client CA cert -> Client key + cert 

我猜的Java在此使用了錯誤的證書情況下,可能是CA或中間證書。

通過添加到p12keychain修復只有客戶端的密鑰和證書,沒有中間體。

不應該-certfile選項(我以前有過)。只需客戶端密鑰/證書。正確的export命令:

openssl pkcs12 -export \ 
    -in client.crt -inkey client.key \ 
    -out client.p12 

client.p12然後可以導入到鑰匙串:

keytool -importkeystore \ 
    -deststorepass changeit -destkeystore keystore \ 
    -srckeystore client.p12 -srcstoretype PKCS12 -srcstorepass changeit 

並進行自定義驗證工作的罰款。

+0

我認爲這與NGINX有關。我們有一個F5和一個NGINX。我們只需要進行這項更改就可以與NGINX進行通信。我想知道我可以對NGINX做出什麼樣的修改來修復它,而不是改變我的證書。 –

相關問題