2016-02-06 19 views
5

Tentativo di implementare l'autenticazione della chiave client (con firma aut.).Autenticazione client con HttpClient

Codice assomiglia:

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

Con -Djavax.net.debug=all Posso vederlo sceglie correttamente il mio certificato, vedo le firme, vedo richiesta di certificato, e non vi ECDHClientKeyExchange, ecc, tutti guarda bene.

Ma comunque mi sto risposta che segue da Nginx (con stato 400):

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

Si noti che per certificato inesatto/nginx chiave di solito scende di sessione, w/o fornire alcun dettaglio in risposta solo testo .

Questo client.p12 opere provenienti da linea di comando, come:

$ 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 

Quindi questa chiave è sicuramente valida. Ma perché non funziona per Java? C'è qualcosa che mi è mancato in java ssl config?

+0

Il certificato è stato importato nel keystore? – STaefi

+0

viene caricato direttamente da 'client.p12'. Ho anche provato a importarlo nel keystore, ma non cambia nulla –

risposta

2

Il problema era che la mia chiave client includeva anche i certificati di firma nella catena di chiavi. Non solo il mio certificato client (che è richiesto per l'autenticazione), ma tutta la catena di certificati (senza chiavi Naturalmente, solo i certificati)

Era:

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

Credo che Java utilizza un certificato di sbagliato in questo caso, forse CA o certificato intermedio.

Risolto aggiungendo a p12 o keychain solo la chiave e il certificato del cliente, senza intermedi.

non deve avere -certfile opzioni (che avevo prima). Solo chiave/certificato cliente. comando corretto esportazione:

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

Questo client.p12 quindi potrebbero essere importati in portachiavi:

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

E ha funzionato bene per l'autenticazione personalizzata.

+0

Penso che questo abbia a che fare con NGINX. Abbiamo un F5 e un NGINX. Dobbiamo solo apportare questa modifica per comunicare con NGINX. Mi piacerebbe sapere quale modifica posso apportare a NGINX per risolvere il problema invece di cambiare i miei certificati. –