HTTPS e mutua autenticazione client/server su Tomcat con certificato X509

Java Tech 3 2057
In questo articolo vedremo come configurare e realizzare una connessione in HTTPS tra un browser e un server Tomcat, con mutua autenticazione, e quindi anche con l’autenticazione del client presso il server, attraverso l’utilizzo di un certificato X509 appositamente generato.

Si presuppone di avere un server Tomcat con un Connettore HTTPS già configurato, che però preveda la sola autenticazione del server presso il client e non il viceversa (il riconoscimento del server presso il client, attraverso apposito certificato installato sul server, è la funzione base necessaria per il funzionamento del HTTPS, insieme alla cifratura dei pacchetti che viaggiano sul canale di comunicazione tra il browser e il web server, in questo caso Tomcat).

Gli strumenti:

  1. OpenSSL (per la prova versione 0.9.8)
  2. JDK 1.6 (keytool)
  3. Tomcat 6
  4. Certification Authority (opzionale)

MutualAuthentication

Step 1

Generare una chiave privata con il seguente comando:

openssl genrsa -des3 -out MiaChiavePrivata.pem 2048

In questo caso abbiamo richiesto la generazione di una chiave privata di lunghezza 2048 bit. Il file MiaChiavePrivata.pem generato sarà protetto da password. Se non si vuole che il file “MiaChiavePrivata.pem” sia protetto da password, è necessario rimuovere l’opzione “-des3”, e cioè:

openssl genrsa -out MiaChiavePrivata.pem 2048

Step 2

Generare il file di richiesta certificato con il seguente comando:

openssl req -new -key MiaChiavePrivata.pem -out cert.csr

Dopo l’esecuzione del comando precedente, il file “cert.csr” contiene la richiesta certificato.

Tale file può essere utilizzato per sottomettere la richiesta alla CA oppure per autogenerare un certificato “self-signed” con il tool OpenSSL.

Il prossimo “Step 3a” descrive lo scenario di richiesta certificato alla CA, mentre lo “Step 3b” descrive lo scenario di autogenerazione di un certificato “self-signed” (che è sensato utilizzare per ambienti prototipali o di test). Gli step sono alternativi.

Step 3a

Sottomettere la richiesta certificato alla CA. Il certificato deve comprendere tra i suoi scopi “Client Authentication” (OID 1.3.6.1.5.5.7.3.2). Come output la CA ci invierà (tipicamente) il file “.cer” (codificato con DER) che contiene la chiave pubblica “certificata” dalla CA stessa, e il file “.cer” che contiene il suo certificato ROOT. Diamo un nome ai file che la CA ci invia: “MioCertificato.cer” e “CARoot.cer”.

Step 3b

Creiamo un file che chiamiamo “certreq.conf”, che deve avere il seguente contenuto:

[ ssl_client ]
basicConstraints = CA:FALSE
nsCertType = client
keyUsage = digitalSignature, keyEncipherment
extendedKeyUsage = clientAuth

In questo modo, tra le altre cose, definiamo anche lo scopo del certificato (extendedKeyUsage = clientAuth).

Creiamo adesso il nostro certificato “self-signed” con il seguente comando:

openssl x509 -req -days 365 -in cert.csr -signkey MiaChiavePrivata.pem -out MioCertificato.cer -extfile certreq.conf -extensions ssl_client

Per fare una verifica del certificato appena creato possiamo eseguire il seguente comando:

openssl x509 -text -noout -in MioCertificato.cer

Step 4

Adesso ci serve generare il certificato “completo” (chiave pubblica + chiave privata) in formato PKCS#12 (“.p12”). Il comando da lanciare è il seguente:

openssl pkcs12 export -in MioCertificato.cer -inkey MiaChiavePrivata.pem -certfile CARoot.cer -out bundle.p12

Il file “bundle.p12” che otteniamo, in questo caso contiene anche il certificato della CA di Root (grazie all’opzione “-certfile”). Quando lo importeremo nel nostro keystore (step 5) verrà importato anche quello della CA di Root.

Step 5

A questo punto, dobbiamo importare sul server  il certificato pubblico del client che vogliamo che il nostro Tomcat accetti come “autenticato”. Tale certificato è contenuto nel file  “MioCertificato.cer”.

Nel file di configurazione del nostro Tomcat, “server.xml”, abbiamo la seguente sezione (che già avremo configurato in precedenza per gestire il protocollo HTTPS):

<Connector port="8443" maxHttpHeaderSize="8192"
 maxThreads="150" minSpareThreads="25" maxSpareThreads="75"
 enableLookups="false" disableUploadTimeout="true"
 acceptCount="100" scheme="https" secure="true"
 SSLEnabled="true" clientAuth="true"
 keystoreFile="/ks/.keystore"
 truststoreFile="/ks/.truststore"
 sslProtocol="TLS" />

Gli attributi da configurare per abilitare la gestione dell’autenticazione dei client sono i seguenti:

clientAuth="true"
truststoreFile="/ks/.truststore"

Il comando da lanciare per effettuare l’importazione del certificato è il seguente:

keytool -import -alias MioClient -keystore "/ks/.truststore" -trustcacerts -file MioCertificato.cer

In alternativa, se abbiamo effettuato lo “Step 3a”, con lo stesso comando di cui sopra possiamo importare il certificato della RootCA. In questo modo il server autenticherà tutti i client in possesso di un certificato emesso dalla RootCA, e non saremo obbligati ad importare ogni nuovo certificato che venga emesso dalla stessa RootCA per autenticare un nuovo client.
Nel nostro caso, il comando da lanciare è il seguente:

keytool -import -alias MiaRootCA -keystore "/ks/.truststore" -trustcacerts -file CARoot.cer

Ogni volta che effettuiamo variazioni sui keystore puntati da Tomcat è necessario effettuare il restart.

Step 6

Siamo pronti per importare il nostro certificato “bundle.p12” nel keystore della postazione client, che in questo caso è un PC Windows (nella nostra prova utilizzeremo il browser Chrome che si appoggia al keystore di Windows come repository dei certificati). Su Windows l’operazione di importazione è abbastanza semplice, perchè basta fare “doppio click” sul file e parte il wizard (la cartella del keystore dove importare il certificato è la “Personal”).

Step 7

L’ultimo passo è la prova.

Colleghiamoci con il nostro browser alla URL del Tomcat server, ad es. https://tomcatserver:8443/ Se abbiamo compiuto correttamente lo Step 6, il browser ci chiederà quale certificato utilizzare per autenticarci presso il server. In questo caso scegliamo quello che abbiamo importato allo Step 6. Se tutto è andato per il verso giusto, dovremmo visualizzare sul browser la home del nostro Tomcat.

Come controprova, potremmo rimuovere il certificato client dal keystore Windows ed effettuare nuovamente la connessione dal browser (per precauzione puliamo la cache del browser prima) al nostro server Tomcat. In questo caso il server dovrebbe rifiutare la connessione e il browser ci dovrebbe presentare una pagina apposita che ci spiega il problema di autenticazione.

E’ possibile abilitare su Tomcat i tracciamenti di debug delle operazioni riguardanti la gestione SSL e della mutua autenticazione, settando la seguente system property (si può aggiungere la proprietà negli script di startup di Tomcat):

-Djavax.net.debug="ssl,handshake"

Alcuni riferimenti:

  1. OpenSSL, Howto Generate Private Key 
    http://www.openssl.org/docs/HOWTO/keys.txt
  2. OpenSSL, Howto Generate Certificate Request 
    http://www.openssl.org/docs/HOWTO/certificates.txt
  3. OpenSSL, Howto Generate PKCS#12 
    http://support.citrix.com/article/CTX106630
Ringraziamenti:
  • A Marco Palma per i preziosi suggerimenti

About the author / 

Salvatore Di Loro

Related Posts

3 Comments

  1. Daniele 24/05/2016 at 09:49 -  Reply

    Avrei bisogno di un’informazione. Per un’applicazione in produzione, entrambe le chiavi (sia server che client) devono essere validati da una CA oppure posso validare solo il certificato del server e generare dei certificati self-signed per i client?

    grazie

    • Salvatore Di Loro 24/05/2016 at 10:35 -  Reply

      Grazie per il commento.
      Premesso che in linea di principio, in ambienti di produzione, non andrebbero mai utilizzati certificati self-signed (che in genere andrebbero usati solo a scopo di test), ma dei certificati emessi da CA riconosciute (CA pubbliche riconosciute su Internet, nel caso di webapp “visibili” da internet, oppure CA private riconosciute solo su Intranet aziendale, nel caso di webapp “visibili” solo da intranet).
      Ad ogni modo, tecnicamente, non c’è nessun problema ad utilizzare certificati self-signed a scopo di autenticazione dei client (è ciò che viene descritto allo “Step 3b” del post). E’ sufficiente importare come “trusted” tali certificati (con la sola chiave pubblica) nel keystore “trusted” puntato da Tomcat (nel caso considerato nel post).
      Il comando da lanciare (citato allo “Step 5”) è il seguente:
      keytool -import -alias MioClient -keystore "/ks/.truststore" -trustcacerts -file MioCertificato.cer
      Spero di avere chiarito il tuo dubbio.

Leave a reply

Your email address will not be published. Required fields are marked *

Instagram

Flickr