Au revoir, au mot de passe le plus connu du monde Java

Contexte

En java, lorsque nous voulons faire des communications sécurisées, nous manipulons des certificats. Pour cela, nous devons généralement ajouter des certificats dans le magasin de clés (keystore). Les configurations peuvent être particulière mais généralement, c’est le fameux cacerts qui est utilisé.

keytool -list -cacerts

Nous obtenons la traditionnelle question où généralement, nous écrivons changeit

Entrez le mot de passe du fichier de clés :

avertissement Avec un JDK plus anciens (< = 8), il faut préciser le magasin en question même si c’est celui par défaut keytool -list -keystore java.home/lib/security/cacerts

Le mot de passe est connu par beaucoup de développeur Java ou administrateur système exploitant des applications Java.

L’information est connue. Elle est tout simplement écrite dans les pages du manuel.

The initial password of the cacerts keystore file is changeit.
System administrators should change that password and
the default access permission of that file upon installing the SDK.

PKCS#12

A l’instar du format JKS (Java KeyStore) spécifique à Java, le format PKCS#12 est une norme de la famille des standards de cryptographie à clé publique (Public-Key Cryptography Standards [PKCS])

Le but de ce format (comme l’était le format JKS) est d’avoir un seul fichier qui contient un ensemble de clé privés et de certificats.

avertissement Cette norme est supportée par la commande openssl.

Le support du format PKCS#12 a été introduit au fur et à mesure des versions de Java.

Une étape importante est franchie dans le JDK 9. En effet la JEP 229 définit le format PKCS12 comme format par défaut pour les magasins de clés (et non plus le format JKS). Cela donne le top départ pour la phase de transition vers PKCS#12 (soit 5 ans depuis septembre 2017) en gardant toujours le support de JKS (aujourd’hui encore)

Deux changements dans le JDK 18

Les deux points que nous allons voir ne sont pas des JEP mais simplement des améliorations.

astuce Comme quoi, il est toujours intéressant de lire les notes de version lors de la sortie d’un JDK.

JDK-8275252: Migrate cacerts from JKS to password-less PKCS12

Le magasins de clé cacerts sera à partir du JDK 18 au format PKCS#12.

Par exemple, en utilisant la commande keytool pour voir le contenu du magasin par défaut du JDK 17, nous voyons que le format utilisé est le format JKS.

/opt/jdk-17.0.1+12/bin/keytool -list -cacerts | head
Enter keystore password:  changeit
Keystore type: JKS
Keystore provider: SUN

Your keystore contains 128 entries

c=at,o=e-commerce monitoring gmbh,cn=globaltrust 2020, Oct 20, 2021, trustedCertEntry,
Certificate fingerprint (SHA-256): 9A:29:6A:51:82:D1:D4:51:A2:E3:7F:43:9B:74:DA:AF:A2:67:52:33:29:F9:0F:9A:0D:20:07:C3:34:E2:3C:9A
c=be,o=globalsign nv-sa,cn=globalsign root e46, Oct 20, 2021, trustedCertEntry,
Certificate fingerprint (SHA-256): CB:B9:C4:4D:84:B8:04:3E:10:50:EA:31:A6:9F:51:49:55:D7:BF:D2:E2:C6:B4:93:01:01:9A:D6:1D:9F:50:58
c=be,o=globalsign nv-sa,cn=globalsign root r46, Oct 20, 2021, trustedCertEntry,
...

Maintenant, avec le JDK 18, en utilisant la commande keytool pour voir le contenu du magasin de clé cacerts fournis, le format est PKCS12.

/opt/jdk-18/bin/keytool -list -cacerts | head
.Keystore type: PKCS12
Keystore provider: SUN

Your keystore contains 89 entries

actalisauthenticationrootca [jdk], Mar 2, 2022, trustedCertEntry,
Certificate fingerprint (SHA-256): 55:92:60:84:EC:96:3A:64:B9:6E:2A:BE:01:CE:0B:A8:6A:64:FB:FE:BC:C7:AA:B5:AF:C1:55:B3:7F:D7:60:66
addtrustexternalca [jdk], Mar 2, 2022, trustedCertEntry,
Certificate fingerprint (SHA-256): 68:7F:A4:51:38:22:78:FF:F0:C8:B1:1F:8D:43:D5:76:67:1C:6E:B2:BC:EA:B4:13:FB:83:D9:65:D0:6D:2F:F2
addtrustqualifiedca [jdk], Mar 2, 2022, trustedCertEntry,
...

JDK-8231107: Allow store password to be null when saving a PKCS12 KeyStore

Ce point correspond en réalité plus à une correction. C’est la possibilité de ne pas fournir de mot de passe. D’où la possibilité de mettre null comme valeur de mot de passe au niveau de l’API.

KeyStore magasin = magasin.getInstance("pkcs12");
...
magasin.store(outputStream, null);

Naturellement, mais c’est mieux en le précisant, nous pourrons lire un magasin PKCS12 sans mot de passe

magasin.load(inputStream, null);

avertissement Cela implique aussi que les certificats inclus dans le magasin ne seront plus chiffrés.

Conclusion

Le JDK 18 passe donc au format PKCS12 sans mot de passe pour son magasin cacerts. Il n’y aura plus de mot de passe changeit à fournir.

Cela sera plus simple et aussi protégé qu’un mot de passe connu par tout le monde.

De plus, les administrateurs pourront même utiliser la commande openssl qui leur sera peut être plus familière par rapport à la commande keytool du JDK.

avertissement En production, pour des raisons de sécurité, il sera toujours possible et nécessaire de définir un mot de passe pour les magasins de clés. Pour rappel, pas de mot de passe implique pas de chiffrement pour les certificats.