2016-02-06 14 views
5

Der Versuch, Client-Key-Authentifizierung (mit selbst signierten ca) zu implementieren.Client-Authentifizierung mit HttpClient

-Code wie folgt aussieht:

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(); 

Mit -Djavax.net.debug=all ich mein Zertifikat sehen richtig wählt, ich sehe Unterschriften, ich Zertifikatsanforderung zu sehen, und es ECDHClientKeyExchange, etc, alles sieht gut aus.

Aber trotzdem erhalte ich folgende Antwort von Nginx (mit dem Status 400):

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

Hinweis, dass für eine falsche Zertifikat/Schlüssel nginx meist Sitzung fällt, w/o eventuell im Klartext Antwort bereitstellt .

Diese client.p12 Werke von der Kommandozeile, wie:

$ 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 

Also dieser Schlüssel ist auf jeden Fall gültig. Aber warum funktioniert es nicht für Java? Gibt es etwas, das ich in Java-SSL-Konfiguration verpasst habe?

+0

Wird Ihr Zertifikat in Ihren Keystore importiert? – STaefi

+0

es wird direkt von 'client.p12' geladen. Ich habe auch versucht, es in Keystore zu importieren, aber es ändert nichts –

Antwort

2

Das Problem bestand darin, dass mein Clientschlüssel auch das Unterzeichnen von Zertifikaten in der Schlüsselkette enthielt. Nicht nur mein Client-Zertifikat (die für die Authentifizierung erforderlich ist), sondern ganz Kette von Zertifikaten (ohne Schlüssel natürlich nur Zertifikate)

Es war:

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

Ich denke, Java ein falsches Zertifikat auf diese verwendet Fall, vielleicht CA oder Zwischenzertifikat.

Fixed durch Hinzufügen zu p12 oder keychain nur Client-Schlüssel und Zertifikat, ohne Zwischenprodukte.

Es sollte nicht haben -certfile Optionen (die ich vorher hatte). Nur Clientschlüssel/Zertifikat Korrekter Exportbefehl ist:

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

Diese client.p12 dann in Schlüsselbund importiert werden kann:

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

und arbeitete für die benutzerdefinierte Authentifizierung in Ordnung.

+0

Ich denke, das hat mit NGINX zu tun. Wir haben eine F5 und eine NGINX. Wir müssen diese Änderung nur vornehmen, um mit NGINX zu kommunizieren. Ich würde gern erfahren, welche Änderungen ich an NGINX vornehmen kann, um es zu reparieren, anstatt meine Zertifikate zu ändern. –