Howto SSL
- Installation
- Gestion clé privée /
certificat
- Générer une demande de certificat (CSR)
- Générer un certificat auto-signé
- Générer un certificat multi-domaines avec subjectAltName
- “Déprotéger” une clé privée
- Ajouter un mot de passe à une clé privée
- Changer le mot de passe d’une clé privée
- Convertir un certificat PEM vers d’autres formats
- Convertir PKEY vers PEM
- Convertir P7B vers CER
- Convertir P7B vers PEM
- Convertir DER vers PEM
- Convertir PEM vers pkcs12
- Utilisation de Let’s Encrypt
- Vérifications
- Voir le contenu d’un certificat ou d’une CSR
- Voir le contenu d’une CRL
- Extraction clé et certificat d’un fichier PFX
- Vérifier la correspondance entre clé privée / certificat / .csr
- Vérifier la correspondance entre le Certificat Intermédiaire et le certificat
- Vérifier qu’un certificat n’est pas révoqué
- Vérifier la conformité d’un certificat en ligne de commande
- testssl
- Vérifier la conformité d’un certificat via des services externes
- Obtenir la liste des certificats émis pour un domaine
- Louer un certificat auprès d’une autorité de certificat
- Sécurité et qualité des certificats
- Ajouter une CA personnalisée
- FAQ
SSL (Secure Sockets Layer) est un protocole de sécurisation des échanges réseau. Cela se base sur un principe de clé privée et clé publique (certificat) signée par une autorité de certification. On parle désormais de SSL/TLS car les normes récentes ont renommé SSL en TLS (Transport Layer Security).
- Documentation : https://www.openssl.org/docs/
- https://wiki.mozilla.org/Security/Server_Side_TLS
- Statut de cette page : prod
Installation
# apt install openssl
$ openssl version
OpenSSL 3.0.9 30 May 2023 (Library: OpenSSL 3.0.9 30 May 2023)
Gestion clé privée / certificat
Générer une demande de certificat (CSR)
Pour générer une clé privée non chiffrée (private.key) et sa demande de certificat associé (demande.csr) à transmettre à une autorité de certification :
$ openssl req -newkey rsa:2048 -sha256 -nodes -keyout private.key -out demande.csr
À des fins pédagogiques, on peut découper la cette génération en 2 étapes, à savoir la génération de la clé privée et la demande de certificat :
$ openssl genrsa -out private.key 2048
$ openssl req -new -sha256 -key private.key -out demande.csr
Pour générer une demande de certificat à partir d’un certificat existant (certificat.crt) :
$ openssl x509 -x509toreq -sha256 -in certificat.crt -out demande.csr -signkey private.key
Générer un certificat auto-signé
- Prérequis : avoir généré une clé et une demande de certificat (voir ci dessus)
- Génération du certificat avec expiration dans 1000 jours :
$ openssl x509 -req -sha256 -days 1000 -in demande.csr -signkey private.key -out certificat.crt
Note : sous Debian, pour regénérer le certificat snakeoil (certificat autogénéré à l’installation) :
# make-ssl-cert generate-default-snakeoil --force-overwrite
Générer un certificat multi-domaines avec subjectAltName
Un certificat avec subjectAltName permet d’ajouter des noms de domaine secondaires (subjectAltName) en plus du nom de domaine principal (Common Name), ce qui est supporté par 99.9% des navigateurs récents,mais cela coûte cher chez les autorités de certification.
Modifier une copie du fichier /etc/ssl/openssl.cnf
avant
de générer le certificat pour :
- Décommenter
req_extensions = v3_req
- Dans la section
[v3_req]
renseigner les domaines :subjectAltName = DNS:$domain1,DNS:$domain2[,...]
Pour générer une demande de certificat pour la transmettre à une autorité de certification :
cp -p /etc/ssl/openssl.cnf /etc/ssl/openssl.cnf.old
openssl req -newkey rsa:2048 -sha256 -nodes -config /etc/ssl/openssl.cnf -extensions v3_req -keyout private.key -out demande.csr
Pour générer un certificat multi-domaines auto-signé :
“Déprotéger” une clé privée
Si une clé privée a été chiffrée (private.pem), on peut générer une version non chiffrée (private.key) ainsi :
$ openssl rsa -in private.pem -out private.key
$ rm private.pem
Ça permet de passer une clée ENCRYPTED PRIVATE KEY
en
PRIVATE KEY
.
Ajouter un mot de passe à une clé privée
$ openssl rsa -in private.pem -aes256 -out private.key
writing RSA key
Enter PEM pass phrase:
Verifying - Enter PEM pass phrase:
Changer le mot de passe d’une clé privée
Il suffit de répéter les 2 étapes ci-dessus :
$ openssl rsa -in private.pem -out private.key
$ openssl rsa -in private.key -aes256 -out private-new.pem
$ rm private.pem private.key
$ mv private-new.pem private.pem
On peut également changer la clé privée d’une CA, par exemple pour OpenVPN, comme ceci :
# openssl rsa -in /etc/shellpki/cakey.key -aes256 -out /etc/shellpki/cakey-new.key
# rm /etc/shellpki/cakey.key
# mv /etc/shellpki/cakey-new.key /etc/shellpki/cakey.key
Convertir un certificat PEM vers d’autres formats
Voir http://security.ncsa.illinois.edu/research/grid-howtos/usefulopenssl.html
Notamment pour PKCS 12 (ou PFX) vers PEM :
$ openssl pkcs12 -export -out output.pfx -inkey private.key -in certificate.crt
$ openssl pkcs12 -in private.pfx -out private.pem
S’il s’agit de la clé :
$ openssl pkcs12 -in private.pfx -nocerts -out private.pem
Convertir PKEY vers PEM
$ openssl pkey -in private.pkey -out private.pem
Convertir P7B vers CER
openssl pkcs7 -print_certs -in certificate.p7b -out certificate.cer
Convertir P7B vers PEM
openssl pkcs7 -inform der -print_certs -in certificate.p7b -out certificate.pem
Convertir DER vers PEM
openssl x509 -inform der -in certificate.cer -out certificate.pem
Convertir PEM vers pkcs12
openssl pkcs12 -export -inkey private.key -in certificate.crt -out private.p12
Utilisation de Let’s Encrypt
Vérifications
Voir le contenu d’un certificat ou d’une CSR
Pour voir le contenu d’un certificat (certificat.crt) :
$ openssl x509 -text -in certificat.crt
Pour voir le contenu d’un certificat d’un service réseau :
$ openssl s_client -connect ssl.example.com:443
Pour voir le contenu d’une demande de certificat (demande.csr) :
$ openssl req -text -in demande.csr
Si besoin d’utiliser un site web pour afficher le contenu d’une CSR, on peut utiliser un outil mis en place par Namecheap.
Pour lire le format PFX :
$ openssl pkcs12 -info -in certificat.pfx
Voir le contenu d’une CRL
Voir la liste des numéros de séries des certificats révoqués.
Si la CRL est encodée en DER :
$ openssl crl -inform DER -text -noout -in crl.pem
Si la CRL n’est pas binaire :
$ openssl crl -inform PEM -text -noout -in crl.pem
Extraction clé et certificat d’un fichier PFX
Extraire la clef :
openssl pkcs12 -in votre.pfx -nocerts -out votre.key -nodes
Extraire le certificat :
openssl pkcs12 -in votre.pfx -clcerts -nokeys -out votre.crt
Vérifier la correspondance entre clé privée / certificat / .csr
Pour s’assurer qu’un certificat est bien issu d’un clé privée, ou d’une demande de certificat (.csr), on peut vérifier la correspondance grâce au modulus que l’on peut extraire et comparer :
$ openssl x509 -noout -modulus -in certificat.crt | openssl md5
$ openssl rsa -noout -modulus -in private.key | openssl md5
$ openssl req -noout -modulus -in demande.csr | openssl md5
Si toutes les empreintes MD5 sont identiques, on est sûr que c’est issu de la clé privée.
Pour vérifier en une seule commande :
$ diff <(openssl rsa -in private.key -modulus | grep Modulus) <(openssl x509 -in certificate.crt -modulus | grep Modulus)
Vérifier la correspondance entre le Certificat Intermédiaire et le certificat
$ openssl verify -untrusted IntermediateCA.crt certificat.crt
Il devra alors répondre :
ssl_certificate.crt: OK
Vérifier qu’un certificat n’est pas révoqué
Il faut d’abord trouver quel serveur OCSP est déclaré :
$ openssl x509 -noout -ocsp_uri -in certificate.crt
http://ocsp.example.com
Puis, interroger le serveur OCSP obtenu (ici http://ocsp.example.com) avec la chaîne de certification (chainfile.pem) et le certificat (certificat.crt) à vérifier :
$ openssl ocsp -issuer chainfile.pem -cert certificat.crt -text -url http://ocsp.example.com
Dans le cas où un proxy filtrant est utilisé, il faut bien penser à autoriser les domaines/IP des serveurs OCSP en question, sinon on récupère une erreur 403 et la requête OCSP n’est pas validée.
Dans le cas d’un certificat révoqué on verra les lignes suivantes :
Cert Status: revoked
Revocation Time: Nov 2 09:30:00 2014 GMT
Vérifier la conformité d’un certificat en ligne de commande
La vérification en ligne de commande nécessite une machine GNU/Linux.
Pour vérifier un fichier de certificat en ligne de commande :
$ openssl verify -CApath /etc/ssl/certs certificat.crt
Pour vérifier la conformité d’un certificat d’un service réseau en ligne de commande :
$ openssl s_client -CApath /etc/ssl/certs -connect ssl.example.com:443
Pour un service réseau en STARTTLS (exemple avec SMTP, valable aussi pour POP3/IMAP/FTP) :
$ openssl s_client -CApath /etc/ssl/certs -connect mail.example.com:25 -crlf -starttls smtp
Pour un service en HTTPS avec l’option SNI qui permet d’envoyer un nom de domaine au sein du protocole SSL/TLS (supporté par 99.9% des navigateurs récents) :
$ openssl s_client -CApath /etc/ssl/certs -servername ssl.example.com -connect 192.0.2.42:443
Le certificat est conforme avec votre base locale de
certificats CA si vous obtenez Verify return code: 0 (ok)
Si le code de retour est différent de 0, le certificat n’est pas conforme pour différentes raisons :
- Verify return code: 21 (unable to verify the first certificate) : le certificat distant est signé par un certificat CA qui n’est pas dans votre base locale ou utilise un certificat intermédiaire inconnu (Note: il peut y avoir toute une chaîne de certification avec plusieurs certificats intermédiaires)
testssl
Le script Bash testssl permet d’effectuer des vérifications très poussées.
# apt install testssl.sh
Examples d’utilisation :
$ testssl www.example.com:443
Service detected: HTTP
Testing protocols via sockets except NPN+ALPN
SSLv2 not offered (OK)
SSLv3 not offered (OK)
TLS 1 not offered
TLS 1.1 not offered
TLS 1.2 offered (OK)
TLS 1.3 offered (OK): final
NPN/SPDY not offered
ALPN/HTTP2 http/1.1 (offered)
Testing cipher categories
...
$ testssl --cipher-per-proto -t=smtp mail.example.com:587
Service set: STARTTLS via SMTP
Hexcode Cipher Suite Name (OpenSSL) KeyExch. Encryption Bits Cipher Suite Name (IANA/RFC)
-----------------------------------------------------------------------------------------------------------------------------
SSLv2
SSLv3
TLS 1
xc014 ECDHE-RSA-AES256-SHA ECDH 253 AES 256 TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA
x39 DHE-RSA-AES256-SHA DH 2048 AES 256 TLS_DHE_RSA_WITH_AES_256_CBC_SHA
x88 DHE-RSA-CAMELLIA256-SHA DH 2048 Camellia 256 TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA
xc019 AECDH-AES256-SHA ECDH 521 AES 256 TLS_ECDH_anon_WITH_AES_256_CBC_SHA
...
Vérifier la conformité d’un certificat via des services externes
Nous conseillons d’utiliser l’outil complet SSL LABS : https://www.ssllabs.com/ssltest/analyze.html
D’autres outils également utiles :
Pour une vérification de la chaîne de certification : https://whatsmychaincert.com/
Pour une vérification avancée : https://ssldecoder.org/
Pour une vérification SSL/TLS orientée SMTP : https://tls.imirhil.fr, https://ssl-tools.net/mailservers
Pour une vérification par divers scanners : https://observatory.mozilla.org/
Obtenir la liste des certificats émis pour un domaine
Une obligation de transparence est demandée auprès des autorités de certification. On peut facilement obtenir la liste des certificats pour un domaine avec https://crt.sh/
Louer un certificat auprès d’une autorité de certificat
Pour louer un certificat lié à UN enregistrement DNS :
- 0 EUR/an : Let’s Encrypt https://letsencrypt.org/
- 0 EUR/an : StartCom/StartSSL Free : https://www.startssl.com/Support?v=1 (attention, cela pose des soucis avec Firefox)
- 8.20 EUR/an : Comodo PositiveSSL : http://www.namecheap.com/ssl-certificates/comodo/positivessl-certificate.aspx
- 12 EUR/an : Gandi SSL standard : http://www.gandi.net/ssl/standard#single
- 129 EUR/an : Thawte SSL123 : http://www.thawte.fr/ssl/ssl123-ssl-certificates/
Pour louer un certificat « wildcard » (pour une infinité de
sous-domaines du type *.example.com
) :
- 85.62 EUR/an : Comodo PositiveSSL : http://www.namecheap.com/ssl-certificates/comodo/positivessl-wildcard-certificate.aspx
- 120 EUR/an : Gandi SSL standard : http://www.gandi.net/ssl/standard#wildcard
- 449 EUR/an : Thawte SSL Web Server Wildcard : http://www.thawte.fr/ssl/wildcard-ssl-certificates/
Pour louer un certificat multi-domaines :
- 40 EUR/an (pour 3 enregistrements DNS) et jusqu’à 210 EUR/an (30 enregistrements DNS) : https://www.gandi.net/ssl/standard#multi
- 129 EUR + 99 EUR par SAN/an : Thawte SSL123 avec SAN : http://www.thawte.fr/ssl/ssl123-ssl-certificates/
Pour louer un certificat EV :
- 249 EUR/an : Thawte SSL Web Server avec EV : https://www.thawte.fr/ssl/extended-validation-ssl-certificates/
À propos de StartCom/StartSSL
Il faut noter que l’offre StartStartSSL Free de StartCom est bien gratuite mais il y a plusieurs inconvénients :
- StarCom/StartSSL a été racheté en 2016 par l’autorité de certification chinoise WoSign qui a de nombreux problèmes selon la fondation Mozilla… ce qui a pour conséquence que Mozilla envisage de retirer les certificats CA de StartSSL, notamment Firefox 51 devrait bannir les certificats émis par StartCom/StartSSL à partir du 21 octobre 2016 !!
- les certificats gratuits mentionnent les informations personnelles de la personne physique qui a créé le compte
- la gestion du renouvellement est lourde (votre compte expire tous les ans, et vous ne pouvez le renouveler que quelques jours avant…)
- vous pouvez créer uniquement des certificats liés à la personne physique qui a créé le compte (nom de domaine qui vous appartient personnellement ou appartient à votre société) : si vous créez plusieurs certificats pour le compte d’autres sociétés (vos clients par exemple) StartSSL finira pas rejeter vos demandes et vous devrez créer un compte pour chaque société
- la révocation d’un certificat est payante (environ 20 EUR)
- différents problèmes et bugs, voir #FAQ
L’avantage de StartSSL est que pour 150 EUR/an, vous pouvez obtenir la validation « Organization » (après une lourde procédure de vérifications) et créer ensuite une infinité de certificats Wildcard valables 3 ans.
À propos de Let’s Encrypt
Let’s Encrypt est un jeune projet qui a pour but de démocratiser l’usage de SSL/TLS pour le web en fournissant facilement des certificats gratuits. Pour plus de détails voir notre HowtoLetsEncrypt
Sécurité et qualité des certificats
Failles de sécurité
Plusieurs failles de sécurité ont touché SSL/TLS ou le logiciel OpenSSL ces dernières années, il convient donc de traiter avec attention la question de la configuration au sein des différents logiciels. Nous détaillons ci-dessous quelques failles célèbres, une liste de toutes les failles étant disponible sur le wiki de Mozilla.
Faille POODLE
La faille POODLE (adding Oracle On Downgraded Legacy Encryption) est une vulnérabilité touchant le protocole SSL version 3.0 permettant une attaque man-in-the-middle. Elle a été révélée en octobre 2014 et il y a eu une vague de désactivation du protocole SSLv3, voir http://disablessl3.com/.
- Désactiver SSL 3.0 pour Apache :
SSLProtocol all -SSLv2 -SSLv3
- Désactiver SSL 3.0 pour Nginx 0.7 :
ssl_protocols TLSv1;
- Désactiver SSL 3.0 pour Nginx 1.2 :
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
- Désactiver SSL 3.0 pour Postfix :
smtpd_tls_mandatory_protocols=!SSLv2,!SSLv3 smtp_tls_mandatory_protocols=!SSLv2,!SSLv3 smtpd_tls_protocols=!SSLv2,!SSLv3 smtp_tls_protocols=!SSLv2,!SSLv3
Faille FREAK
La faille FREAK (Factoring RSA Export Keys) est une vulnérabilité dans OpenSSL permettant une attaque man-in-the-middle pour renégocier un chiffrement faible. Cela se base sur des chiffrements « EXPORT » introduits dans les années 2000 par les USA pour pouvoir déchiffrement les communications. Voir http://blog.cryptographyengineering.com/2015/03/attack-of-week-freak-or-factoring-nsa.html, https://freakattack.com/#sysadmin et https://www.smacktls.com/.
On peut tester si un serveur accepte les chiffrements EXPORT avec la commande suivante :
$ openssl s_client -connect example.com:443 -cipher EXPORT
Si on obtient error:14077410:SSL routines:SSL23_GET_SERVER_HELLO:sslv3 alert handshake failure:s23_clnt.c:749 c’est que le serveur n’accepte pas les chiffrements EXPORT.
Debian a
corrigé cette faille en janvier2015, ce qui est surtout important
pour les clients (navigateurs, etc.). On peut vérifier que sa machine ne
tolère pas de chiffrements « EXPORT » via la commande
openssl ciphers | tr -s ':' '\n' | sort | grep EXP
. Sous
Debian, par défaut Apache et Nginx n’ont pas été impactés car leur liste
de chiffrement n’incluait pas EXPORT.
Avoir A+ sur SSL LABS
L’outil https://www.ssllabs.com/ssltest/analyze.html permet d’avoir une note symbolique sur la configuration d’un serveur HTTPS.
Voici quelques critères pour avoir une bonne note :
- la taille de la clé privée est d’au moins 2048 bits (4096 bits est recommandé mais cela impacte les performances) ;
- le certificat et le(s) certificat(s) intermédiaire(s) utilisent des fonctions de hashage en SHA-2 (et non plus en SHA-1 qui est déprécié) ;
- le serveur HTTPS n’autorise pas l’utilisation d’algorithmes de chiffrement « faibles » avec le client (comme RC4, MD5, etc.) ;
- pour implémenter le principe de Forward Secrecy, le serveur HTTPS utilise des paramètres DH (Diffie-Hellman) d’au moins 2048 bits (ou 4096 bits si c’est la taille de la clé privée) ;
- le serveur HTTPS autorise le protocole TLS 1.2 ;
- le serveur HTTPS permet la réutilisation des sessions SSL ;
- le serveur HTTPS support l’OCSP stapling ;
- un entête Strict-Transport-Security indique que le site n’est consultable qu’en HTTPS pendant au moins 180 jours.
Plus généralement, on utilisera la documentation de référence https://wiki.mozilla.org/Security/Server_Side_TLS#Recommended_configurations et notamment le générateur de configuration SSL de Mozilla.
Configuration Apache
En pratique avec Apache (sous Debian 8), voici une configuration SSL avancée :
SSLProtocol All -SSLv2 -SSLv3
SSLCipherSuite AES128+EECDH:AES128+EDH
SSLHonorCipherOrder On
SSLCompression off
#SSLSessionTickets off
SSLSessionCache shmcb:/var/log/apache2/ssl_sessioncache(10240000)
SSLUseStapling yes
SSLStaplingReturnResponderErrors off
SSLStaplingCache shmcb:/var/log/apache2/ssl_staplingcache(2048000)
Header always set Strict-Transport-Security "max-age=15552000"
Voici une configuration minimale :
SSLEngine on
SSLCertificateFile /etc/ssl/certs/secure.crt
SSLCertificateKeyFile /etc/ssl/private/secure.key
#SSLCertificateChainFile /etc/ssl/certs/certificates_chain.CA.crt
SSLProtocol All -SSLv2 -SSLv3
Configuration Nginx
En pratique avec Nginx (sous Debian 8), voici une configuration SSL avancée :
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
ssl_ciphers "AES128+EECDH:AES128+EDH";
ssl_prefer_server_ciphers on;
#ssl_session_tickets off;
ssl_session_cache shared:SSL:10m;
ssl_session_timeout 1d;
ssl_stapling on;
ssl_stapling_verify on;
add_header Strict-Transport-Security "max-age=15552000";
ssl_dhparam /etc/ssl/dhparam.pem;
Note : il faut générer ses propres paramètres Diffie-Hellman ; pour des paramètres de 2048 bits (attention, c’est un peu long), on fera:
$ openssl dhparam -out /etc/ssl/dhparam.pem 2048
Vérifier que la création soit bien effectué :
$ openssl dhparam -inform PEM -in /etc/ssl/dhparam.pem -check -text
Désactiver SSLv3
Voici un lien qui donne la configuration à appliquer pour désactiver SSLv3 pour chaque service : http://disablessl3.com/
Ajouter une CA personnalisée
Pour ajouter une CA personnalisée et lui faire confiance globalement
(par exemple pour Elasticsearch en mode TLS), il faut placer le
certificat de la CA dans
/usr/local/share/ca-certificates/my-ca.crt
puis exécuter la
commande update-ca-certificates
. Il faut bien que le
fichier de certificat se termine par .crt
sinon il sera
ignoré.
FAQ
Erreur “The OCSP server has no status for the certificate” avec StartSSL
Suite à la mise en place d’un nouveau certificat délivré par StartSSL, vous obtenez une erreur du type “An error occurred during a connection to ssl.example.com. The OCSP server has no status for the certificate. (Error code: sec_error_ocsp_unknown_cert) ?
StartSSL semble mettre entre 6 et 12h à propager ses nouveaux certificats sur son serveur OCSP. Il faut donc patienter…
Bug avec Firefox et l’interface d’administration de StartSSL
Il y a un bug avec l’interface d’administration StartSSL avec Firefox (Firefox embarque un mauvais certificat). Voir le bug report https://bugzilla.mozilla.org/show_bug.cgi?id=1037080 et une solution temporaire : https://forum.startcom.org/viewtopic.php?p=8204#p8204
Il faut supprimer le certificat “StartCom? Certification Authority” de l’autorité StartCom de type “Securité personne” (Software Security Device) dans les préférences de Firefox (Avancée –> Certificat). Voir https://lut.im/EPSYOXoy/ckEgJEwU
Une autre “astuce” est d’utiliser un autre navigateur…
Ajouter des certificats CA sous Debian
Afin d’ajouter des certificats CA il faut copier les fichiers .crt
dans /usr/local/share/ca-certificates/
puis exécuter :
# dpkg-reconfigure ca-certificates