TLS/SSL avec Tomcat

TLS/SSL permet de sécuriser les communications réseau grâce à un chiffrement basé sur un échange de clés.

Tomcat peux utiliser des certificats au format PKCS#12 (créés avec OpenSSL) ou JKS (créés avec keytool).


Certificat JKS

Les manipulations et configurations présentées ici peuvent être faites avec Tomcat 5.5+ et avec un JDK 1.4+. Elles fonctionnent aussi avec JBoss AS 4 -> 7.

Paramétrage Tomcat 8.5+

Cette configuration peut être faites avec Tomcat 8.5 ou plus récent.

Le paramétrage de Tomcat se fait dans le fichier conf/server.xml. Il faut activer le connecteur sécurisé, habituellement sur le port 8443.

   <Connector port="8543" SSLEnabled="true">
       <SSLHostConfig>
           <Certificate certificateKeystoreFile="conf/tomcatserver.jks" certificateKeystorePassword="sewapass" />
       </SSLHostConfig>
   </Connector>

Les requêtes sécurisées devront avoir une URL de type https://myserver:8443/....

Afin que cela puisse fonctionner, il faut que le serveur soit en mesure de fournir une clé et un certificat, issu d'un keystore. Ce fichier keystore peut être généré avec l'utilitaire keytool.

Paramétrage Tomcat 8-

Cette configuration peut être faites avec Tomcat 5.5 -> 8.0. Elles fonctionnent aussi avec JBoss AS 4 -> 7.

Comme pour les versions plus récentes, le paramétrage de Tomcat se fait dans le fichier conf/server.xml, sur un format un peu plus simple.

   <Connector port="8443" scheme="https" secure="true"
              clientAuth="true" sslProtocol="TLS" 
              ... />

Génération du keystore

Le keystore est un fichier qui stocke un ensemble de couples clé privé / clé publique, auxquels on attache des certificats. Pour générer un keystore au format JKS, on utilise keytool, qui est dans le JDK.

 keytool -genkey -alias sewatech-fr -keypass sewapass -storepass sewapass
                 -keystore tomcatserver.jks -keyalg RSA 
                 -dname "cn=www.sewatech.fr, o=Sewatech, c=FR"

Cette commande va générer une clé pour le site www.sewatech.fr. Si le fichier tomcatserver.jks existe déjà, la nouvelle clé est ajoutée, sinon le fichier est créé pour cette première clé.

Utilisé en l'état, la clé est auto-signée. C'est à dire qu'aucune autorité, autre que l'auteur lui-même, n'a certifié la validité de la clé. Les navigateurs refusent donc d'établir une connexion sécurisée avec le site qui produit la clé, sauf si on lui demande explicitement d'accepter, via une gestion des exceptions. La solution pour rassurer le navigateur, est de faire certifier la clé par une autorité tierce.

Remarque : pour les vieux Tomcat (<= 6), il fallait donner le même mot de passe au magasin et à la clé ; ce n'est plus le cas.

Demande de certificat

La demande de certificat est un fichier au format PKCS#10 généré à partir de la clé.

 keytool -certreq -file sewatech.csr 
         -alias sewatech-fr -keystore tomcatserver.jks -storepass sewapass

Le fichier csr doit ensuite être envoyé à l'autorité de certification (CA) qui retournera un certificat X.509 ou une chaîne de certificats. Un certificat est produit pour valider les informations du propriétaire de la clé ; ce certificat fait référence à un certificat parent qui valide les informations de l'autorité. Ces certificats peuvent être attachés les uns aux autres à plusieurs niveaux, formant une chaîne. Le certificat, ou la chaîne, sont au format PKCS#7 ou PEM, ces deux formats étant supportés par keytool. Si l'autorité retourne le certificat sous un autre format, il est nécessaire de le transformer à l'aide d'un outil comme OpenSSL.

En possession d'un certificat au bon format, nous pouvons à présent l'importer et l'attacher à notre clé.

 keytool -importcert -file sewatech.cer
         -alias sewatech-fr -keystore tomcatserver.jks -storepass sewapass               

Si le nom de domaine correspond bien au CN de la clé, le navigateur acceptera de naviguer par SSL, si l'autorité qui a certifié notre clé a été déclarée dans sa configuration. Par exemple, une autorité comme StartCom n'est que dans la configuration par défaut de Firefox.

Problèmes de format

Des petits problèmes de format peuvent se poser au moment d'importer le certificat.

Par exemple, j'ai demandé un certificat "Personal E-mail Certificates" à Thawte, qui en propose gratuitement, à usage de développement. keytool a été incapable de l'importer (information valable en mars 2009). Il existe des outils qui le remettent en format compatible, mais n'ayant aucune garantie sur leurs origines, je préfère ne pas faire de lien vers eux.

Autre exemple, StartCom fournit des certificats X.509, au format PEM. keytool ne peut pas l'importer seul, il a besoin de la chaîne de certificat, qu'il faut reconstituer par simple concaténation de fichiers. J'ai donc utilisé le script ci-dessous :

 wget http://www.startssl.com/certs/ca.crt
 wget http://www.startssl.com/certs/sub.class1.server.ca.crt
 cat sewatech.crt sub.class1.server.ca.crt ca.crt > sewatech.cer
 keytool -import -keystore tomcatserver.jks -trustcacerts -alias sewatech-fr -file sewatech.cer

Certificat PKCS

Les certificats de ce type sont générés par OpenSSL. Ils peuvent être utilisés sous plusieurs formes dans Tomcat.

Paramétrage Tomcat 8.5+ - APR

On peut utiliser un certificat OpenSSL via un connecteur APR. C'était l'unique façon de faire dans les anciennes versions de Tomcat / Java.

Pour ça, il faut au préalable installer Tomcat Native. Attention, à partir de Tomcat 9, il faut tcnative en version 1.2+.

Ensuite, on configure un connecteur en forçant le protocole à HTTP/1.1 + APR.

   <Connector port="8541" SSLEnabled="true" 
              protocol="org.apache.coyote.http11.Http11AprProtocol"
              SSLCertificateFile="conf/tomcat.crt" SSLCertificateKeyFile="conf/tomcat.key"/>

J'utilise l'ancien format de configuration pour <Connector>. Il fonctionne toujours avec Tomcat 9.

Paramétrage Tomcat 8.5+ - JSSE

On peut utiliser un certificat PKCS#12 de la même manière qu'un certificat PKS, en utilisant l'implémentation JSSE.

   <Connector port="8543" SSLEnabled="true">
       <SSLHostConfig>
           <Certificate certificateKeystoreFile="conf/tomcatserver.pfx" certificateKeystorePassword="sewapass" />
       </SSLHostConfig>
   </Connector>

Paramétrage Tomcat 8.5+ - OpenSSL

On peut utiliser le même certificat PKCS#12 en forçant l'implémentation OpenSSL.

   <Connector port="8543" SSLEnabled="true" 
              sslImplementationName="org.apache.tomcat.util.net.openssl.OpenSSLImplementation">
       <SSLHostConfig>
           <Certificate certificateKeystoreFile="conf/tomcatserver.pfx" certificateKeystorePassword="sewapass" />
       </SSLHostConfig>
   </Connector>

D'après les tests faits par les développeurs de Tomcat, cette implémentation est plus rapide. Par contre, elle impose l'installation de Tomcat Native.

Création du certificat

 # Commun pour le connecteur APR et les connecteurs classiques
 openssl req -newkey RSA:2048 -nodes -keyout tomcat.key -x509 -days 365 -out tomcat.crt
 
 # Inutile pour le connecteur APR
 openssl pkcs12 -inkey tomcat.key -in tomcat.crt -export -out tomcat.pfx

Rérérences