Introduction

Imaginons que vous développiez une application Java EE tournant dans un serveur Tomcat. Imaginons que vous interrogiez cette application soit depuis votre navigateur, soit depuis un client java développé par vos soins. Imaginons enfin que vous souhaitiez tester le comportement de l'application dans un contexte SSL, par exemple pour vérifier que tel protocole que vous souhaitez mettre en place et qui s'appuie sur la couche SSL fonctionne bien, ou que vous vouliez tester l'utilisation de cookies sécurisés, ou encore que vous souhaitiez vérifier le comportement du navigateur dans un cadre où certaines ressources sont sécurisées et d'autres non, etc.

Dans tous ces cas, vous aurez besoin de mettre en place une communication SSL entre votre serveur d'applications et votre application cliente, et c'est ce que nous allons expliquer dans ce tutoriel.

I. Génération du certificat autosigné pour Tomcat

Dans le cadre de ce tutoriel, on considère le cas le plus simple d'un test en local, et localhost est utilisé comme nom d'hôte. En cas de communication entre deux machines distinctes, il faut bien sûr s'adapter pour donner au serveur Tomcat un certificat basé sur sa dénomination publique, et de même dans le cas de la configuration de la machine cliente.

Pour générer un certificat autosigné, il faut utiliser l'outil « keytool » fournit par java. Naviguez via un terminal en ligne de commande jusqu'au répertoire d'installation de votre jdk et accédez au dossier bin. Puis exécutez la commande suivante :

 
Sélectionnez

keytool -genkey -keyalg RSA -alias mylocaltomcat1 -keystore C:\PATH\TO\YOUR\keystore.jks -validity 365 -keysize 2048 -storepass myKeystorePassword -keypass myKeystorePassword

À ce stade l'outil vous pose une série de questions. Vous pouvez répondre ce que vous voulez à la plupart, mais à la première « quels sont vos noms et prénoms », vous devez absolument répondre « localhost », de manière à ce que lors de la demande de confirmation il vous propose « CN=localhost ». Ceci est très important et vous évitera la désagréable surprise d'une exception de type « java.security.cert.CertificateException: No name matching localhost found », voir aussi ici pour plus de détails sur ce problème. Concernant la génération de la clé proprement dite vous pouvez consulter aussi dzone et ce paragraphe en français tiré d'un cours sur Android pour plus de détails sur la signification des paramètres utilisés qui ne sont pas forcément optimaux.

II. Configuration de Tomcat

Éditez le fichier server.xml de Tomcat et recherchez la ligne suivante :

xml
Sélectionnez

<Connector connectionTimeout="20000" port="8080" protocol="HTTP/1.1" redirectPort="8443" />

Supprimez la redirection sur le port 8443 dont nous ne voulons plus :

xml
Sélectionnez

<Connector connectionTimeout="20000" port="8080" protocol="HTTP/1.1"/>

Recherchez à présent la section dédiée au port 8443 qui est commentée par défaut et décommentez là. Ajoutez les paramètres manquants « keystoreFile » et « keystorePass » pour obtenir un résultat du type :

xml
Sélectionnez

    <Connector port="8443" protocol="HTTP/1.1" SSLEnabled="true"
               maxThreads="150" scheme="https" secure="true"
               clientAuth="false" sslProtocol="TLS" 
               keystoreFile="C:\PATH\TO\YOUR\keystore.jks"
               keystorePass="myKeystorePassword"/>

Démarrez le serveur. Si tout se déroule bien, vous devriez voir passer les lignes suivantes et aucune erreur à propos d'un fichier de clés introuvables.

 
Sélectionnez

juin 10, 2013 8:38:46 PM org.apache.coyote.AbstractProtocol init
INFO: Initializing ProtocolHandler ["http-bio-8080"]
juin 10, 2013 8:38:46 PM org.apache.coyote.AbstractProtocol init
INFO: Initializing ProtocolHandler ["http-bio-8443"]

Connectez-vous sur votre application via une url en « https://localhost:8443/monappli/ » pour valider qu'elle est bien accessible désormais (vous devriez avoir un avertissement du navigateur comme quoi vous accédez à un certificat autosigné, ce qui est normal).

Nous nous plaçons ici dans le cas le plus simple où un seul certificat est stocké dans votre fichier jks. Si ce n'est pas votre cas, il faut ajouter un paramètre keyAlias dans la déclaration de votre connecteur (dans notre exemple ce serait keyAlias="mylocaltomcat1") afin d'indiquer à Tomcat lequel choisir (faute de quoi il prendra le premier qui vient). Au besoin les documentations officielles (en anglais) vous fourniront tous les détails nécessaires sur la configuration du SSL dans Tomcat et sur ses connecteurs http.

III. Configuration du poste Client

Dans le cadre d'un accès à votre serveur Tomcat en https avec votre navigateur, vous pouvez accepter manuellement le certificat. Mais dans le cas d'un accès M2M où c'est une autre machine qui accède à votre serveur Tomcat, elle va probablement rejeter le certificat et vous renvoyer une exception de type « sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target ». Pour éviter cela, nous allons suivre la documentation officielle d'Oracle.

Téléchargez le fichier InstallCert.java. Si vous ne savez pas comment le compiler en ligne de commande, je vous propose tout simplement de créer un nouveau projet Éclipse, d'y créer une nouvelle classe portant ce nom et d'y copier-coller le code en corrigeant le nom du package suivant vos besoins. Cette classe étant faite pour être exécutée en ligne de commande, vous pouvez soit exporter le projet sous la forme d'un exécutable jar, soit l'exécuter depuis votre IDE, par exemple de la manière suivante, en l'appelant depuis une autre classe et en lui passant les arguments de la ligne de commande sous forme de paramètres :

java
Sélectionnez

public class MyInstallCert {
    public static void main(String[] args)  throws Exception{
        InstallCert.main("localhost:8443");
    }
}

Une petite explication, ce programme va télécharger le certificat SSL de l'hôte qu'on lui communique et créer un fichier de certification Java compréhensible par la JVM. Dans l'exemple précédent, nous nous situons dans le cas le plus simple où la communication M2M a lieu au sein du même serveur physique, et bien évidemment, le serveur Tomcat doit être démarré pour permettre le téléchargement du certificat que nous avons créé au I.

Attention, une fois qu'il a analysé le certificat, le programme vous demande une confirmation avant de l'enregistrer. Appuyez simplement sur « Entrée », puis récupérez le fichier généré et copiez-collez le dans le dossier « jre\lib\security » du répertoire d'installation de la JRE de la machine qui a besoin de communiquer avec votre serveur Tomcat. Si vous souhaitez que toutes les applications Java le reconnaissent, vous pouvez même faire ce que suggère Oracle, et supprimer le fichier « cacerts » originel pour renommer votre fichier nouvellement généré sous ce nom-là.

Conclusion

Nous avons vu comment mettre en place une communication autosignée de machine à machine en java/java EE dans le cas le plus simple. Dans une perspective d'entreprise, l'étape suivante passerait par la mise en place d'une CA (Autorité de Certification), chargée d'émettre et de vérifier des certificats pour votre réseau d'entreprises, ce qui pourra s'avérer utile dès lors que vous intégrerez des applications écrites dans un autre langage, ou que votre parc informatique deviendra trop grand pour qu'il soit humainement viable de réitérer n fois les opérations décrites précédemment. Malheureusement ce sujet passe les bornes de ce tutoriel, je vous renvoie donc à la documentation officielle d'Oracle (en anglais) si vous désirez approfondir la question.

Remerciements

Au moment de publier enfin cet article, je voudrais remercier ram-000 et keulkeul pour leur relecture technique et leurs conseils, zoom61 pour sa relecture orthographique, et djibril pour son aide dans l'utilisation des outils de rédaction.