Comment les noms de serveurs de certificats SSL sont-ils résolus/puis-je ajouter des noms alternatifs en utilisant keytool?

ces questions peuvent être formulées séparément pour plus de clarté, mais elles se rapportent toutes à la même question.

comment les noms de serveurs de certificats SSL sont-ils résolus?

pourquoi les navigateurs semblent-ils utiliser le champ CN du certificat, alors que le mécanisme de Java semble ne considérer que les "noms alternatifs sujets"?

est-il possible d'ajouter d'autres noms à un certificat SSL en utilisant keytool? Si non, est d'utiliser openSSL à la place un bon option??

Juste un peu de contexte: j'ai besoin de pour obtenir d'un serveur principal de communiquer avec plusieurs serveurs en utilisant le protocole HTTPS. Évidemment, nous ne voulons pas acheter de certificats SSL pour chaque serveur (il pourrait y en avoir beaucoup), donc je veux utiliser des certificats auto-signés (j'ai utilisé keytool pour les générer). Après que j'ai ajouté les certificats comme confiance dans L'OS, les navigateurs (IE et Chrome) acceptent volontiers la connexion comme confiance. Cependant, même après l'ajout de l' certificats à cacerts Java, Java n'acceptera toujours pas la connexion comme fiable et lance L'Exception suivante:

causé par: java.sécurité.cert.CertificateException: aucun sujet Autres noms présent au coucher du soleil.sécurité.util.HostnameChecker.matchIP (HostnameChecker.java: 142) au coucher du soleil.sécurité.util.HostnameChecker.match (HostnameChecker.java: 75) at com.sun.net.ssl.interne.ssl.X509TrustManagerImpl.checkIdentity(X509T rustManagerImpl.java: 264) at com.sun.net.ssl.interne.ssl.X509TrustManagerImpl.checkServerTrusted( X509TrustManagerImpl.java: 250) at com.sun.net.ssl.interne.ssl.ClientHandshaker.serverCertificate (Clien tHandshaker.java: 1185) ... 14 plus de

j'ai trouvé que je peux faire confiance à Java le certificat implémentant mon propre HostNameVerifier, que j'ai copié d'ici: COM.soleil.jbi.interne.sécurité.http.DefaultHostnameVerifier juste pour tester (soit dit en passant, le nom d'hôte passé comme argument au HostnameVerifier est correct, donc je pense qu'il aurait dû être accepté).

j'ai utilisé le champ de certificat CN comme nom d'hôte (généralement l'adresse IP).

est-ce que quelqu'un peut me dire si je fais quelque chose de mal et m'indiquer la bonne direction?

60
demandé sur dgvid 2011-12-09 12:50:17

1 réponses

la façon de procéder à la vérification du nom d'hôte est définie dans RFC 6125 , qui est très récente et qui généralise la pratique à tous les protocoles, et remplace RFC 2818 , qui était spécifique à HTTPS. (Je ne suis même pas sûr que Java 7 utilise la RFC 6125, qui pourrait être trop récente pour cela.)

From RFC 2818 (Section 3.1) :

si une extension subjectAltName de type DN nom est présent, qui doit être utilisé comme identité. Autrement, le nom commun (le plus spécifique) champ dans le champ Objet du certificat doit être utilisé. Bien l'Utilisation du nom commun est une pratique existante, elle est dépréciée et Les autorités de Certification sont encouragées à utiliser le DN-nom à la place.

[...]

dans certains cas, L'URI est spécifié comme une adresse IP plutôt qu'une hôte. Dans ce cas, l'adresse ip subjectAltName doit être présent dans le certificat et doit correspondre exactement à L'IP dans L'URI.

essentiellement, le problème spécifique que vous avez vient du fait que vous utilisez des adresses IP dans votre CN et non un nom d'hôte. Certains navigateurs peuvent fonctionner parce que tous les outils ne suivent pas strictement cette spécification, en particulier parce que "la plus spécifique" dans la RFC 2818 n'est pas clairement définie (voir les discussions dans la RFC 6215).

si vous utilisez keytool , à partir de Java 7, keytool a une option pour inclure un nom de sujet alternatif (voir la table dans la documentation pour -ext ): vous pouvez utiliser -ext san=dns:www.example.com ou -ext san=ip:10.0.0.1 .

EDIT:

vous pouvez demander un SAN dans OpenSSL en changeant openssl.cnf (il sélectionnera la copie dans le répertoire courant si vous ne voulez pas éditer la configuration globale, autant que je me souvienne, ou vous pouvez choisir un emplacement explicite en utilisant la variable d'environnement OPENSSL_CONF ).

définir les options suivantes (trouver les sections appropriées entre parenthèses en premier):

[req]
req_extensions = v3_req

[ v3_req ]
subjectAltName=IP:10.0.0.1
# or subjectAltName=DNS:www.example.com

il y a aussi une bonne astuce pour utiliser une variable d'environnement pour cela (plutôt que de la fixer dans un fichier de configuration) ici: http://www.crsr.net/Notes/SSL.html

87
répondu Bruno 2011-12-09 13:58:24