Pour ajouter une autorité dans le KeyStore de la JVM Java

publicité
SSL Handshake Failure, lors de l'appel d'un Web Service en HTTPS
Written by LECLERE
Thursday, 04 April 2013 16:53 - Last Updated Thursday, 04 April 2013 17:40
Contexte :
Lorsque l'on tente de faire un appel à un Web Service en HTTPS depuis une JVM Java, on
rencontre souvent le message suivant :
Received fatal alert: handshake_failure
at
com.sun.net.ssl.internal.ssl.Alerts.getSSLException(Alerts.java:174)
at com.sun.net.ssl.internal.ssl.Alerts.getSSLException(Alerts.java:136)
at com.sun.net.ssl.internal.ssl.SSLSocketImpl.recvAlert(
SSLSocketImpl.java:1657)
at com.sun.net.ssl.internal.ssl.SSLSocketImpl.readRecord(
SSLSocketImpl.java:932)
at com.sun.net.ssl.internal.ssl.SSLSocketImpl.performInitialHandshake(
SSLSocketImpl.java:1096)
at com.sun.net.ssl.internal.ssl.SSLSocketImpl.startHandshake(
SSLSocketImpl.java:1123)
at com.sun.net.ssl.internal.ssl.SSLSocketImpl.startHandshake(
SSLSocketImpl.java:1107)
at posslu.Main.main(Main.java:22)
Java Result: 1
La première cause est un problème de configuration de la chaîne de validation du Certificat
SSL. Je vais vous expliquer cela dans la suite ...
Rappel : Différence entre HTTP et HTTPS
HTTP signifie « Hypertext Transport Protocol », ce qui traduit juste la façon dont deux
systèmes communiquent sur le Web (Un navigateur - Internet Explorer, Firefox, Chrome, ... qui est utilisé pour parcourir les pages exposées par un serveur Web - Internet Information
Server, Tomcat, WebSphere, ...).
L’important, c'est la lettre « S » qui fait toute la différence entre HTTP et HTTPS. Le « S »
(grande surprise) est synonyme de «
Secure
(i.e. sécurité) » (par exemple : https://intranet.softcomputing.com).
1/7
SSL Handshake Failure, lors de l'appel d'un Web Service en HTTPS
Written by LECLERE
Thursday, 04 April 2013 16:53 - Last Updated Thursday, 04 April 2013 17:40
En conséquence :
- Si le protocole est non sécurisé (HTTP), cela signifie que les données sont échangées en
clair entre le serveur et le client. Donc, si vous remplissez un formulaire Web et que vous le
soumettez, toutes les informations sont envoyées telles quelles vers le serveur. Et donc, si
quelqu'un espionne le réseau entre le client et le serveur (plusieurs outils existent tel tcpdump),
il peut voir en clair toutes les informations saisies dans le formulaire. - Si, par contre, le protocole est sécurisé (HTTPS), le client et le serveur conviennent au
préalable d'une clé commune pour chiffrer toutes les informations qui vont être échangées entre
le client et le serveur. Ainsi, le même espion que précédemment verra toujours passer les
paquets réseau, mais cette fois-ci, les informations échangées ne seront plus directement
lisibles. Et plus la clé de chiffrement est forte, plus il sera difficile de déchiffrer les paquets. Comment activer le protocole HTTPS Sécurisé ?
La mise en oeuvre du protocole HTTPS se fait sur le serveur Web :
- En activant dans la configuration du serveur les connecteurs adéquats
Par exemple, pour le serveur d'application Tomcat, dans le fichier server.xml, on ajoutera
la section suivante : - <Connector port="8443" protocol="HTTP/1.1" SSLEnabled="true" maxThreads="150" scheme="https" secure="true" clientAuth="false" sslProtocol="TLS" >
-
En Ajoutant un certificat SSL Web sur le serveur Web
Par exemple, pour le serveur Apache, dans le fichier httpd.conf, on ajoutera les
éléments suivants : - SSLEngine on - SSLCertificateFile /path/to/www.exemple.com.cert - SSLCertificateKeyFile /path/to/www.exemple.com.key Comment opère la chaîne de certification SSL ?
2/7
SSL Handshake Failure, lors de l'appel d'un Web Service en HTTPS
Written by LECLERE
Thursday, 04 April 2013 16:53 - Last Updated Thursday, 04 April 2013 17:40
Un Certificat Electronique est un ensemble de données contenues dans un fichier et
précisant :
- Au moins une clé publique ; - Des information d'identification du détenteur du certificat (exemple : nom, localisation,
adresse email) ; - Des informations de validité (date d'expiration, ...) ; - Au moins une signature de l'autorité qui certifie l'exactitude des informations contenues
dans le certificat. Sur ce principe, quand une communication est initiée entre le client Web et le serveur Web, le
serveur Web présente au client Web le Certificat Electronique qui lui est attaché. Le client
Web commence par vérifier auprès de l'
autorité de certification
déclarée dans le certificat lui même que celui-ci est bien valide (
délivré par cette autorité , pas expiré ni révoqué
), et si tel est le cas, en extrait la
clé publique
pour pouvoir chiffrer le canal de communication.
Là ou ça commence à se compliquer, c'est qu'il n'y à pas qu'une seule autorité de
certification
. On peut
acheter des
certificats SSL
chez plusieurs fournisseurs (
Verisign
,
RapidSSL
, ...). C'est la raison pour laquelle, chaque fournisseur de
certificat SSL
, qui fait
office d'autorité locale
de certification pour ses propres
certificats SSL
doit être déclaré auprès d'une
autorité de certification supérieure
qui va garantir que le fournisseur en question est autorisé à délivrer des
certificats SSL
.
3/7
SSL Handshake Failure, lors de l'appel d'un Web Service en HTTPS
Written by LECLERE
Thursday, 04 April 2013 16:53 - Last Updated Thursday, 04 April 2013 17:40
Donc au moment de la validation, le client Web remonte toute la chaîne : de l'autorité de
certification locale
(celle du fournisseur du certificat) jusqu'à l'
autorité de certification racine
.
En conséquence :
- Le client Web doit donc connaitre toute la chaîne pour pouvoir réaliser cette opération. - S'il s'agit du Navigateur Web (Internet Explorer, ...) ces éléments sont enregistrés dans la
magasin des certificats. Et qu'en est-il de JVM Java ?
Pour la JVM Java, le principe est le même que pour le navigateur, à savoir, les éléments de
configurations des
certificats (Certificat Web, Autorité de Certification
locale ou racine
) sont
stockés dans le contexte de la JVM dans un
KeyStore
.
Par défaut, lors de l'installation de la JVM Java, un ensemble de KeyStore sont installés :
- Par exemple : - Si la JVM Java est installée dans le dossier JAVA_HOME ; - Les éléments de la KeyStore sont disponibles dans le dossier %JAVA_HOME%jrelibsec
urity
- On peut alors consulter le détail des autorités de certification installées en natif dans la
JVM Java
4/7
SSL Handshake Failure, lors de l'appel d'un Web Service en HTTPS
Written by LECLERE
Thursday, 04 April 2013 16:53 - Last Updated Thursday, 04 April 2013 17:40
avec la commande :
- %JAVA_HOME%binkeytool -list -keystore %JAVA_HOME%jrelibcacerts - Qui produit une sortie du type : - Type de fichier de clés :
JKS Fournisseur de fichier de clés : SUN Votre fichier de clés d'accès contient 79
entrées
digicertassuredidrootca, 16 avr. 2008, trustedCertEntry, Empreinte du certificat (SHA1) :
05:63:B8:63:0D:62:D7:5A:BB:C8:AB:1E:4B:DF:B5:A8:99:B2:4D:43
trustcenterclass2caii, 29 avr. 2008, trustedCertEntry, Empreinte du certificat (SHA1) :
AE:50:83:ED:7C:F4:5C:BC:8F:61:C6:21:FE:68:5D:79:42:21:15:6E Pour ajouter une autorité dans le KeyStore de la JVM Java
?
Il arrive parfois qu'une autorité de certification ne soit pas connue de la JVM Java (nouveau
fournisseur de
certificat SSL
, ancienne version de la
JVM Java
), il faudra alors ajouter manuellement les éléments de l'autorité de certification du fournisseur
dans la
KeyStore
de la
JVM Java
.
- Cette opération se fait avec l'utilitaire keytool, et la commande suivante :
- %JAVA_HOME%binkeytool -import -alias <alias_authority> -keystore
%JAVA_HOME%jrelibsecuritycacerts -storepass <password> -file
<path_to_authority_certificate_file>
En précisant les éléments suivants :
- <alias_authority> : le nom sous lequel l'autorité de certification sera identifiée dans le
5/7
SSL Handshake Failure, lors de l'appel d'un Web Service en HTTPS
Written by LECLERE
Thursday, 04 April 2013 16:53 - Last Updated Thursday, 04 April 2013 17:40
KeyStore ;
- <password> : Le mot de passe pour ouvrir le KeryStore ;
- <path_to_authority_certificate_file> : Le chemin vers le fichier Certificat SSL de
l'autorité de certification récupéré auprès du fournisseur.
Cas des Certificats auto-signés ?
Pour les besoins du développement ou du test, il arrive que l'on doivent créer un certificat
SSL
sans
pouvoir passer par un
fournisseur agrée
. On utilise à lors un
Certificat SSL auto-signé
, c'est à dire qu'il fait office de
certificat SSL
mais aussi d'
autorité de certification
.
Ce type de certificat SSL n'est pas utilisable sur des environnements de production car rien
ne permet de valider l'origine du certificat et les différents clients du service émettent un
Warning lors de l'utilisation d'un tel certificat (Internet Explorer, Chrome, ...).
Bien entendu, la JVM Java déclenche elle aussi une erreur si l'on tente d'utiliser ce type de
certificat, car la chaîne de confiance entre le client et le serveur n'est pas assurée.
Pour palier ce problème, il faut appliquer la même méthode que précédemment, mais cette
fois on ne peut pas se baser sur le certificat de l'autorité de certification (puisqu'elle n'existe
pas), et on va utiliser le
6/7
SSL Handshake Failure, lors de l'appel d'un Web Service en HTTPS
Written by LECLERE
Thursday, 04 April 2013 16:53 - Last Updated Thursday, 04 April 2013 17:40
certificat SSL auto-signé
lui-même,
- et la commande sera : - %JAVA_HOME%binkeytool -import -v -trustcacerts -alias <alias_authority> -keystore
%JAVA_HOME%jrelibsecuritycacerts -storepass <password> -file
<path_to_authority_certificate_file>
- En précisant les éléments suivants :
- <alias_authority> : le nom sous lequel l'autorité de certification sera identifiée dans le
KeyStore ;
- <password> : Le mot de passe pour ouvrir le KeryStore ;
- <path_to_authority_certificate_file> : Le chemin vers le fichier Certificat SSL de
l'autorité de certification récupéré auprès du fournisseur.
Pour aller plus loin :
-
HTTPS sur Wikipedia
Certificat SSL sur Wikipedia
Autorité de Certification sur Wikipedia
Java Keystore sur Wikipedia
7/7
Téléchargement