J'essaie d'obtenir le certificat d'un serveur distant, que je peux ensuite utiliser pour ajouter à mon magasin de clés et l'utiliser dans mon application Java.
Un développeur senior (qui est en vacances :() m'a informé que je peux exécuter ceci:
openssl s_client -connect Host.host:9999
Pour récupérer un certificat brut, que je peux ensuite copier et exporter. Je reçois la sortie suivante:
depth=1 /C=NZ/ST=Test State or Province/O=Organization Name/OU=Organizational Unit Name/CN=Test CA
verify error:num=19:self signed certificate in certificate chain
verify return:0
23177:error:14094410:SSL routines:SSL3_READ_BYTES:sslv3 alert handshake failure:s3_pkt.c:1086:SSL alert number 40
23177:error:140790E5:SSL routines:SSL23_WRITE:ssl handshake failure:s23_lib.c:188:
J'ai aussi essayé avec cette option
-showcerts
et celui-ci (fonctionnant sur debian, pensez-vous)
-CApath /etc/ssl/certs/
Mais obtenez la même erreur.
Cette source dit que je peux utiliser cet indicateur CApath mais que cela ne semble pas aider. J'ai essayé plusieurs chemins en vain.
S'il vous plaît laissez-moi savoir où je vais mal.
Il s'avère qu'il y a plus de complexité ici: je devais fournir beaucoup plus de détails pour que cela fonctionne. Je pense que cela a quelque chose à voir avec le fait que c'est une connexion qui a besoin de l'authentification du client, et le hankshake avait besoin de plus d'informations pour continuer jusqu'au stade où les certificats ont été vidés.
Voici ma commande de travail:
openssl s_client -connect Host:port -key our_private_key.pem -showcerts \
-cert our_server-signed_cert.pem
Espérons que ceci est un coup de pouce dans la bonne direction pour quiconque pourrait faire avec quelques informations supplémentaires.
Si le serveur distant utilise SNI (c'est-à-dire qu'il partage plusieurs hôtes SSL sur une même adresse IP), vous devrez envoyer le nom d'hôte correct pour obtenir le bon certificat.
openssl s_client -showcerts -servername www.example.com -connect www.example.com:443 </dev/null
Si le serveur distant n'utilise pas SNI, vous pouvez ignorer le paramètre -servername
:
openssl s_client -showcerts -connect www.example.com:443 </dev/null
Pour afficher tous les détails du CERT d'un site, vous pouvez également utiliser cette chaîne de commandes:
$ echo | \
openssl s_client -servername www.example.com -connect www.example.com:443 2>/dev/null | \
openssl x509 -text
Bien que je sois d’accord avec la réponse de Ari (et son vote plus élevé :), il me fallait faire une étape supplémentaire pour que cela fonctionne avec Java sous Windows (où il devait être déployé):
openssl s_client -showcerts -connect www.example.com:443 < /dev/null | openssl x509 -outform DER > derp.der
Avant d'ajouter la conversion openssl x509 -outform DER
, Keytool de Windows m'avait signalé une erreur en se plaignant du format du certificat. Importer le fichier .der a bien fonctionné.
La ligne de commande la plus simple pour cela, qui inclut la sortie PEM pour l'ajouter au magasin de clés, ainsi qu'une sortie lisible par l'homme et prend également en charge SNI, ce qui est important si vous travaillez avec un serveur HTTP est la suivante:
openssl s_client -servername example.com -connect example.com:443 \
</dev/null 2>/dev/null | openssl x509 -text
L'option - nom_serveur permet d'activer le support SNI et l'option openssl x509 -text imprime le certificat au format lisible par l'homme.
One-Liner pour extraire le certificat d'un serveur distant au format PEM, en utilisant cette fois sed
:
openssl s_client -connect www.google.com:443 2>/dev/null </dev/null | sed -ne '/-BEGIN CERTIFICATE-/,/-END CERTIFICATE-/p'
Pour obtenir le certificat du serveur distant, vous pouvez utiliser l'outil openssl
. Vous pouvez le trouver entre BEGIN CERTIFICATE
et END CERTIFICATE
que vous devez copier et coller dans votre fichier de certificat (CRT).
Voici la commande qui le démontre:
ex +'/BEGIN CERTIFICATE/,/END CERTIFICATE/p' <(echo | openssl s_client -showcerts -connect example.com:443) -scq > file.crt
Pour renvoyer tous les certificats de la chaîne, ajoutez simplement g
(global) comme suit:
ex +'g/BEGIN CERTIFICATE/,/END CERTIFICATE/p' <(echo | openssl s_client -showcerts -connect example.com:443) -scq
Ensuite, vous pouvez simplement importer votre fichier de certificat (file.crt
) dans votre trousseau et le rendre fiable. Ainsi, Java ne devrait pas se plaindre.
Sous OS X, vous pouvez double-cliquer sur le fichier ou glisser-déposer dans votre trousseau d'accès afin qu'il apparaisse dans login/certificats. Ensuite, double-cliquez sur le certificat importé et faites-le Toujours faire confiance à SSL.
Sur CentOS 5, vous pouvez les ajouter au fichier /etc/pki/tls/certs/ca-bundle.crt
(et exécuter: Sudo update-ca-trust force-enable
) ou, dans CentOS 6, les copier dans /etc/pki/ca-trust/source/anchors/
et exécuter Sudo update-ca-trust extract
.
Sous Ubuntu, copiez-les dans /usr/local/share/ca-certificates
et exécutez Sudo update-ca-certificates
.
Host=gmail-pop.l.google.com
PORT=995
openssl s_client -servername $Host -connect $Host:$PORT < /dev/null 2>/dev/null | openssl x509 -outform pem
Vous pouvez obtenir et stocker le certificat racine du serveur à l'aide du script bash suivant:
CERTS=$(echo -n | openssl s_client -connect $Host_NAME:$PORT -showcerts | sed -ne '/-BEGIN CERTIFICATE-/,/-END CERTIFICATE-/p')
echo "$CERTS" | awk -v RS="-----BEGIN CERTIFICATE-----" 'NR > 1 { printf RS $0 > "'$SERVER_ROOT_CERTIFICATE'"; close("'$SERVER_ROOT_CERTIFICATE'") }'
Écrasez simplement les variables requises.
pour imprimer uniquement la chaîne de certificat et non le certificat du serveur:
# MYHOST=myhost.com
# MYPORT=443
# openssl s_client -connect ${MYHOST}:${MYPORT} -showcerts 2>/dev/null </dev/null | awk '/^.*'"${MYHOST}"'/,/-----END CERTIFICATE-----/{next;}/-----BEGIN/,/-----END CERTIFICATE-----/{print}'
mise à jour de CA Trust sur CentOS/RHEL 6/7:
# update-ca-trust enable
# openssl s_client -connect ${MYHOST}:${MYPORT} -showcerts 2>/dev/null </dev/null | awk '/^.*'"${MYHOST}"'/,/-----END CERTIFICATE-----/{next;}/-----BEGIN/,/-----END CERTIFICATE-----/{print}' >/etc/pki/ca-trust/source/anchors/myca.cert
# update-ca-trust extract
sur CentOS/RHEL 5:
# openssl s_client -connect ${MYHOST}:${MYPORT} -showcerts 2>/dev/null </dev/null | awk '/^.*'"${MYHOST}"'/,/-----END CERTIFICATE-----/{next;}/-----BEGIN/,/-----END CERTIFICATE-----/{print}' >>/etc/pki/tls/certs/ca-bundle.crt
Si votre serveur est un serveur de messagerie (MS Exchange ou Zimbra), vous devez peut-être ajouter les drapeaux starttls
et smtp
:
openssl s_client -starttls smtp -connect Host_EMAIL:SECURE_PORT 2>/dev/null </dev/null | sed -ne '/-BEGIN CERTIFICATE-/,/-END CERTIFICATE-/p' > CERTIFICATE_NAME.pem
Où,
Host_EMAIL est le domaine du serveur, par exemple, mail-server.com.
SECURE_PORT est le port de communication, par exemple, 587 ou 465
CERTIFICATE_NAME nom du fichier de sortie (format BASE 64/PEM)
Pour le bénéfice de personnes comme moi qui ont essayé de suivre les bons conseils donnés ici en accédant à AWS CloudFront mais ont échoué, l'astuce consiste à ajouter -servername domain.name..
.