web-dev-qa-db-fra.com

Utiliser openssl pour obtenir le certificat d'un serveur

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.

306
nasty pasty

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.

38
nasty pasty

Avec SNI

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

Sans SNI

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
401
Ari Maniatis

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é.

66
David Jaquay

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.

32
Florian

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'
24
André Fernandes

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.

23
kenorb
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
8
akond

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.

4
Andrei Aleksandrov

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
4

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)

1
SHoko

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...

Source: https://serverfault.com/a/780450/8972

1
Amos Shapira