Lorsqu’on accède à certains services internes à une entreprise ou à des environnements hors production, les certificats sont valides dans le système mais pas dans le trustStore par défaut de Java.

Modification du truststore Java

La première solution est d’ajouter les certificats racine dans le trustStore de Java présent dans le $JAVA_HOME/lib/security/cacerts avec le mot de passe changeit.

Solution efficace, fonctionne sur tous les environnements. Seulement, si on a plusieurs versions de Java, il faut le faire pour chacune. Dans les bonnes pratiques, on met à jour son environnement régulièrement, ce qui implique qu’à chaque mise à jour de Java, on doit remettre à jour ce cacerts à la main.

Lors d’une mise à jour d’un certificat, rebelote, on repasse sur tous les truststores pour ajouter le certificat manquant.

Utiliser le certificat système

La deuxième solution est d’utiliser le truststore du système. Sous Windows, on peut injecter le truststore système en ajoutant dans les options de la JVM les configurations suivantes :

-Djavax.net.ssl.trustStore=NUL
-Djavax.net.ssl.trustStoreType=Windows-ROOT

Sous macOS, la commande suivante peut potentiellement fonctionner :

-Djavax.net.ssl.trustStore=/Library/Keychains/System.keychain
-Djavax.net.ssl.trustStoreType=KeychainStore

D’accord, mais faut-il ajouter ces paramètres à chaque lancement de build ? Heureusement, on peut définir ces paramètres dans la variable JAVA_TOOL_OPTIONS. Et voilà, on injecte nos arguments dans toutes les commandes Java mais aussi dans le compilateur javac. Cela impactera aussi les builds de Maven et Gradle.

On peut ajouter la variable JAVA_TOOL_OPTIONS dans un .bashrc ou .zshrc en fonction de son interpréteur.

export JAVA_TOOL_OPTIONS="-Djavax.net.ssl.trustStoreType=KeychainStore"

Plus besoin de gérer les certificats de l’entreprise.


Outils intéressant pour générer des certificats : mkcert

Sources :