Dans l'enfer du SSL

description The ultimate SSL Guideline
Intro

Dans l’enfer du SSL

La cryptographie est un domaine tellement spécifique qu’il n’est pas rare que même les spécialistes en sécurité n’en saisissent que superficiellement les nuances.
Le domaine d’application que l’on rencontre le plus couramment est celui du chiffrement HTTPS et des certificats pour nos sites Web. Aujourd’hui, le consensus est de passer son site sur le Lab SSL de Qualys et d’ajuster sa configuration pour obtenir vaille que vaille un A.

On aura probablement croisé les termes de Perfect Forward Secrecy ou de Padding Oracle sans s’y attarder plus que cela.
Bonne nouvelle: on peut très bien vivre comme ça.
L’objet de cet article est plutôt de vous permettre de comprendre toutes les notions que vous manipulez sans les connaître. Un compréhension plus fine vous permettra de gérer SSL comme une rock star : The Ultimate SSL Guide !

Ce qu’il faut comprendre pour ne pas s’embrouiller


SSL c’est le “s” de “https”

SSL (Secure Sockets Layer) est effectivement une “couche” de sécurité qui s’insère entre des protocoles existants du modèle OSI pour les sécuriser : en mettant une couche SSL entre TCP et HTTP, on permet HTTPS (idem pour FTPS, SMTPS, IMAPS, …).
L’idée étant de disposer d’un moyen de sécuriser les communications sur Internet sans avoir à tout refaire en amont et en aval.

Il est donc faux de se représenter SSL comme une couche, ajoutée tout en haut, pour garantir la sécurité. C’est un moyen intermédiaire inséré dans les couches existantes.
C’est un peu comme si on avait décidé d’envoyer son courrier dans un coffre fort par la poste : on peut toujours faire appel à la poste (TCP) qui transporte le coffre-fort (SSL). Et on peut toujours utiliser une enveloppe (HTTP) que l’on place dans le coffre-fort (SSL).

SSL ou TLS

TLS !
En somme, SSL a été développé par Netscape (à qui l’on doit bien d’autres choses) : première version en 1994, v2 en 1995, v3 en 1996. Mais un moment l’IETF a trouvé que c’était bien et qu’il fallait standardiser ça, ce qui a donné TLS (Transport Layer Security) v1.0 en 1999.
Dès lors, Netscape n’a plus eu besoin de maintenir le projet SSL car c’est désormais sous le giron de la communauté number one d’Internet.
Donc, tandis que TLS continuera d’évoluer (v1.1 en 2006, v1.2 en 2008, v1.3 en 2018), SSL n’aura plus de nouvelle version. Pire ! des vulnérabilités seront trouvées petit à petit dans ses différentes versions, ce qui aboutira à leur décomissionnement (la v1 avant même de sortir, la v2 en 2011, la v3 en 2015).
Donc aujourd’hui seul TLS est standard… mais comme il n’est rien de plus dur que de faire perdre des habitudes aux humains (cf la cigarette et l’esclavage), on parle encore régulièrement de “SSL” ou de “SSL/TLS” pour désigner ce protocole.

C’est mieux SSL, OpenSSL ou AES ?

Ce ne sont pas les mêmes choses. Il y a en fait 4 niveaux d’abstraction mobilisés dans le “chiffrement SSL” :

  1. Les algorithmes disponibles (ex: AES, DES, RC4, RSA, SHA, MD5, …)
  2. L’ordonnancement de ces algorithmes, aussi appelée ciphersuite (DES-CBC3-SHA, ECDHE-RSA-AES128-GCM-SHA256, DHE-RSA-CAMELLIA128-SHA, …)
  3. Le protocole qui applique ces algorithmes à l’établissement d’une connexion sûre (SSL v2, SSL v3, TLS 1.0, …)
  4. L’implémentation de ce protocole (OpenSSL, GnuTLS, LibreSSL, …)
Pour chacun de ces 4 niveaux, il y a des bons et des mauvais choix. Et il n’est pas trivial de s’y retrouver. Néanmoins comprendre la différence entre ces 4 niveaux vous donne déjà 10 brasses d’avance sur le commun des mortels.

SSL c’est le certificat ?

Non.
Si vous avez déjà rencontré la notion de certificat, peut être que la dénomination “certificat SSL” vous aura induit en erreur. Cette appellation tient au fait qu’il s’agit du certificat qu’on utilise pour SSL. Le nom correct est certificat X.509 (du nom de sa norme), il en existe d’autres.
SSL et TLS utilisent des certificats X.509 mais SSL et TLS ne SONT PAS les certificats (et vice versa). Les certificats sont seulement utilisés pour deux des étapes d’une communication SSL/TLS (parmi une bonne vingtaine).

Qu’est-ce qui peut mal tourner ?

Nous l’avons vu, il y a 4 niveaux d’abstraction dans l’utilisation de SSL/TLS. Il n’est pas indispensable d’aller très loin dans les explications techniques, mais nous allons voir les quatre.
Si vous arrivez à bout du premier, vous aurez passé le plus touffu de cet article.

Les algorithmes

Il faut le savoir, tous les algorithmes ne se valent pas. Certains sont réputés pour leur sûreté, certains sont soumis au doute et d’autres sont officiellement décommissionnés.
Ce statut va dépendre de plusieurs éléments :

  • Les cryptanalystes découvrent parfois des “failles” mathématiques permettant de contouner la sécurité d’un algorithme.
  • Il arrive aussi que la progression des puissances de calcul les mette à mal.
  • On soupçonne parfois certaines agences de renseignement d’avoir trouvé un moyen de briser un algorithme et de le garder secret ( pour des raisons évidentes link ).
  • Enfin, certains algorithmes sont si peu utilisés, et donc si peu audités, que même s’il n’existe pas d’attaque connue contre eux, on soupçonne qu’il serait possible d’en trouver une en y accordant du temps (que personne n’a envie de prendre).
Donc, évidemment on évite de choisir ceux qui sont publiquement déclassés et on est prudent sur les autres. Bonne nouvelle, ce n’est pas à vous d’arbitrer, d’autres s’en sont chargé.

Par contre mauvaise nouvelle, il n’y a pas un seul type d’algorithme mais 3 … pour 4 usages. Et c’est bien de comprendre les distinctions. Donc allons-y :

  1. Les algorithmes pour chiffrer les communications (on s’en doute, c’est la fonction première)
  2. Les algorithmes pour envoyer la clé de chiffrement de manière sécurisée (hé oui ! avant de chiffrer, il faut que les deux parties se partagent une clé secrète). Il se trouve qu’ils servent aussi à garantir l’authenticité du site Web et la signature numérique
  3. Les algorithmes de contrôle d’intégrité (pour s’assurer qu’il n’y a pas eu d’erreur ou de malversation durant la transmission des informations). Aussi appellés “fonctions de hachage”. Ils sont également impliqués dans la signature numérique.
Si vous êtes déjà familier avec ces notions, vous pouvez sauter directement au prochain chapitre.

La première classe d’algorithme est assez intuitive. Pour chiffrer les communications, on utilise des algorithmes qui prennent en entrée une clé secrète, un texte et qui sortent une version chiffrée link .
Lorsque le client (le navigateur Web) envoie ce paquet chiffré au serveur (ou vice versa), ce dernier utilise la même clé secrète pour inverser le processus et retrouver le message original. Si vous n’avez que le message chiffré mais pas la clé secrète, vous ne pouvez rien en faire. On nomme ce procédé le chiffrement symétrique link .

Private key encryption

Les algorithmes les plus communs de cette classe sont DES (ancien standard), AES (aussi appelé Rijndael, nouveau standard depuis 2001), RC4 (prononcé ARC FOUR), Blowfish (conçu par Bruce Schneier considéré plus ou moins comme Dieu link dans le milieu), Twofish (son successeur), Serpent, Camellia (standard japonais), SEED (Sud coréen), IDEA, …
En fait en 2001, le NIST a fait un concours pour élire un nouveau standard qui remplacerait le DES (vieillissant) où plusieurs algorithmes se sont affrontés (dont Rijndael, Twofish et Serpent) et le gagnant est devenu AES (Advanced Encryption Standard).
Les standards étatsuniens faisant souvent autorité au dela de leurs frontières, c’est AES qui est l’algorithme le plus utilisé et considéré comme “probablement” le plus sûr. DES n’est plus sécurisé. Une variante, 3DES (TripleDES), a été mise en place pour prolonger sa vie, mais c’est un choix bancal.

Lorsqu’on utilise un chiffrement symétrique, l’idée est que seul le message chiffré transite sur Internet (qui n’est pas un canal de confiance car il peut être espionné) mais jamais la clé. Toute personne qui prendrait frauduleusement connaissance de cette clé pourrait déchiffrer les échanges seccrets entre le client et le serveur.
Pour pouvoir chiffrer la communication, il faut donc que le client et le serveur aient pu préalablement convenir d’une clé secrète commune via un canal sûr (typiquement pas par un message en clair via Internet). Le chiffrement symétrique est aussi parfois appelé “chiffrement à clé (pré)partagée” (pre-shared key, PSK, en anglais) pour cette raison.
Sauf que dans notre cas, quand je vais sur un site en HTTPS, je n’ai pas le temps qu’il m’envoie par la poste une clé secrète ou qu’il m’appelle ou qu’il se déplace avec une valise diplomatique (comme à la bonne époque). C’est là qu’entrent en jeu les algorithmes de la seconde classe.

Il se trouve que depuis la fin des années 70, on dispose d’algorithmes capables d’échanger des données chiffrées sans avoir besoin de partager une clé secrète préalablement. On nomme ce procédé le chiffrement asymétrique. Comment fait-on ? Des maths… donc je vous l’épargne.
Pour simplifier, au lieu d’avoir une clé unique qui sert à chiffrer et à déchiffrer et que les deux interlocuteurs doivent posséder à l’identique, on a ici deux clés. L’une est publique et peut être révélée à n’importe qui (c’est le fameux certificat X.509 !), elle peut donc être envoyée par Internet même si ce canal n’est pas sûr. Cette clé permet seulement de chiffrer. La seconde est privée, ne doit jamais être divulguée et sert uniquement à déchiffrer.

Public key encryption

Inconvénient: c’est un processus lent, on ne peut pas échanger rapidement beaucoup de données de cette manière. Solution: on utilise ce moyen seulement pour s’échanger une clé de chiffrement symétrique et tout le reste de la communication se fait avec un des algorithmes de la première classe.

Comble de la praticité, on peut utiliser ces mêmes algorithmes pour garantir l’authenticité via une signature numérique. Recevoir un message chiffré c’est bien, on est sûr que personne hormis nous et l’emetteur n’a pu le lire, mais ça ne nous dit pas qui est l’émetteur. La signature numérique permet de prouver cela. C’est encore le certificat (la clé publique du site Web) qui sera impliqué dans ce processus.

Les algorithmes de chiffrement asymétriques sont donc utilisés pour ce que l’on nomme l’échange de clé initial et la signature. Les plus connus sont RSA, DH (Diffie-Hellman), ECDH (Elliptic curve Diffie–Hellman… en gros des maths ++).

Troisième et dernière classe d’algorithme, les fonctions de hachage.
Ces algorithmes permettent de réduire des données de n’importe quelle taille à une sortie de taille fixe (par exemple: 71f72c362a1a997ff5abcac8f270949314139e33), que l’on nomme empreinte et qui permet quasi-assurément de distinguer la moindre erreur dans la transmission.
En effet lorsque l’on calcule deux fois l’empreinte d’une même donnée (par exemple une clé de chiffrement), le résultat sera toujours identique peu importe la date, la machine utilisée, etc. Par contre, une modification, ne serait-ce que d’un seul bit sur des millions, donne une empreinte complétement différente.

L’idée sous-jacente est que chiffrer les données c’est bien mais si quelqu’un peut les altérer (sans les lire, seulement en interceptant et en modifiant le message chiffré) et que lorsque je déchiffre le message je reçois “RDV à 12:00” alors qu’en fait on m’a envoyé “RDV à 22:00”, c’est problématique.
En combinant ces algorithmes avec les algorithmes asymétriques, on devient capable de savoir avec certitude si le message est bien conforme à l’original ou s’il a été modifié.

Ces algorithmes participent à la signature numérique du processus (l’infalsifiabilité). Les plus connus sont MD5, SHA-1, SHA256.
Ce qui détermine le niveau de confiance à accorder à de tels algorithmes c’est l’existence ou non de possibilités de modifier “facilement” un message en retombant sur la même empreinte (auquel cas l’utilisateur légitime n’est plus sûr que son message n’a pas été altéré). C’est pour cette raison que MD5 a été décommissionné en 1996 et SHA-1 en 2017.

Voilà on a vu le plus dur.

Les cipher suite

Voyez une cipher suite comme un menu donc chaque plat est un algorithme. Les entrées ce sont les algorithmes d’échange de clé, le plat de résistance c’est l’algorithme de chiffrement et le dessert c’est l’algorithme de hachage.
Pour créer une cipher suite on compose son menu: “pour l’échange de clé je vais faire confiance à RSA avec une clé de 2048 bits, pour le chiffrement je vais prendre de l’AES en mode CBC avec une clé de 128 bits et pour le hachage je vais prendre du SHA256.” Ce qui donnerait la cipher suite TLS_RSA_WITH_AES_128_CBC_SHA … oui oui ça ressemble à ça.

Pour être plus exact, il y a deux syntaxes: la syntaxe propre de l’IANA et celle toute moisie héritée de OpenSSL mais à laquelle vous serez le plus souvent confronté. Une table de correspondance se trouve ici.
En gros, OpenSSL omettait ce qu’il considérait comme par défaut, donc si l’algorithme d’échange de clé était RSA, il n’apparaissait pas. L’équivalent OpenSSL de TLS_RSA_WITH_AES_128_CBC_SHA est donc AES128-SHA.
Dans les deux cas, tout n’est pas explicité (notamment la taille des clés de l’algorithme d’échange de clé), mais ça reste moins la misère avec la nomenclature de l’IANA.
Chaque version de SSL/TLS dispose d’une multitude de cipher suites. Quand une est déclassée, ce n’est pas forcément un cataclysme, il en reste normalement d’autres.

Nous avons vu dans la catégorie précédente qu’il y avait des algorithmes plus ou moins fiables. Partant du principe que vous ne choisissez que de bons algorithmes, qu’est-ce qui pourrait mal se passer avec les cipher suite ?

Premièrement les algorithmes de votre cipher suite peuvent être bons mais utilisés avec des tailles de clé trop faibles. RSA est robuste mais seulement avec des clés d’au moins 2048 bits. En dessous il y a un risque que les puissances de calculs actuelles puissent être suffisantes pour “casser” la clé.
On considère actuellement que les algorithmes asymétriques doivent utiliser au minimum 2048 bits (4096 pour du vraiment touchy) et les algorithmes symétriques du 128 bits (256 pour du haut niveau). Une fonction de hachage cryptographiquement sûre doit aussi produire des empreinte d’au moins 128 bits. Donc si votre cipher suite utilise les bons algos mais avec de mauvaises tailles de clé, c’est mauvais. Par exemple TLS_DH_RSA_WITH_ARIA_128_GCM_SHA256 utilise AES avec une clé de 128 bits (bon) et TLS_RSA_WITH_AES_256_CBC_SHA256 utilise AES avec une clé de 256 bits (très bon). Malheureusement la taille des clés asymétriques (dans l’exemple précédent DH-RSA et RSA) est rarement indiquée dans la nomenclature.
Il y a aussi des raisons historiques de ne pas utiliser certaines cipher suite. Par exemple vous verrez peut être parfois la mention “EXPORT” ou “EXP” comme dans EXP-RC4-MD5 (syntaxe openssl). Il s’agit d’un reliquat de l’époque ou la cryptographie était considérée comme une arme de guerre. Tout “export” d’une arme de guerre étant drastiquement régulée, les étatsuniens bridaient tous les chiffrements destinés à être utilisés hors du territoire.
Dans le cas de EXP-RC4-MD5, RSA est utilisé avec une clé de 512 bits (quand vous passez de 512 à 513 vous doublez le niveau de sécurité, un bon niveau pour RSA, c’est maintenant 2048 bits…) et RC4 est utilisé avec une clé de 40 bits (au lieu de 128).

Deuxième écueuil : les modes de chiffrement. C’est assez complexe donc je vais simplifier. Certains algorithmes symétriques chiffrent les données en les découpant en blocs de taille fixe et en faisant des opérations sur ces blocs. Il y a plusieurs façons de faire, plusieurs modes.
Notamment des cas où 2 blocs identiques seront toujours chiffrés de la même manière (mode ECB) et d’autres où on essayera d’éviter ça (mode CBC par exemple). Choisir le bon mode dépend du type de données qui seront chiffrées, de la quantité, etc. Typiquement, le mode ECB n’est pas du tout adapté à une communication HTTPS.
Donc, en plus d’utiliser les bons algorithmes de chiffrement, il faut les utiliser de la bonne manière. Par exemple TLS_DHE_PSK_WITH_AES_128_GCM_SHA256 utilise AES en mode GCM (très bon) et TLS_RSA_PSK_WITH_AES_256_CBC_SHA utilise AES en mode CBC (moins bon).

Vous pouvez aussi tomber sur des sites utilisant un chiffrement “null”. Comme ECDH-ECDSA-NULL-SHA. Là ça signifie que le site utilise seulement son certificat pour prouver son identité mais qu’il ne chiffre pas le contenu de la connexion.

Autres mauvaises cipher suites: les anonymes : ADH-RC4-MD5 par exemple. ADH signifie Anonymous Diffie Hellman. Il s’agit du cas où la connexion utilisait un autre algorithme d’échange de clé que celui du certificat. Du coup le certificat ne pouvait pas être utilisé pour garantir l’identité du site.
C’est l’inverse du “null”, vous dialoguez en chiffré mais vous ne savez pas avec qui.

C’est pour ces raisons que nombre de tuto SSL indiquent d’ajouter les mentions suivantes dans une conf Apache :

SSLCipherSuite !aNULL:!eNULL:!EXP

Aujourd’hui les certificats sont taillés pour pouvoir échanger des clés via Diffie-Hellman, donc on a pu supprimer le A de ADH. Mais mieux encore, on s’est dit que ce serait bien que toute compromission d’un certificat (si un méchant pirate découvre un jour la clé privée de l’algorithme d’échange) ne mette pas en péril la confidentialité de ce qui a été chiffré par le passé. Car en l’état, s’il a enregistré une communication chiffrée et qu’il découvre un jour la clé, il peut déchiffrer le paquet ou la clé symétrique est envoyée et déchiffrer tout le reste de la communication.
Pour s’affranchir de ce problème, on utilise maintenant la clé du certificat uniquement pour signer une clé publique temporaire qui servira uniquement à échanger la clé symétrique. Et la clé privée temporaire n’a jamais à être transmise (donc pas d’interception possible) et est jetée à l’issue du processus donc elle ne peut être compromise à l’avenir. En permettant que les communications passées ne puissent être violées on assure ce qui s’appelle la Perfect Forward Secrecy (PFS) On dit alors qu’on utilise des clé éphémères et on appose un E pour Ephemeral Diffie-Hellman (DHE ou ECDHE). Cela revient à utiliser un algo asymétrique pour échanger une autre clé asymétrique (jetable) pour échanger une clé symétrique (jetable aussi).

Somme toute, ceci ne vous concerne pas directement, mais si vous voyez un jour ce vocable, vous comprendrez mieux les tenants et aboutissants.
De votre côté, la seule chose à retenir, c’est que l’IANA distingue toutes les cipher suites selon si elles sont recommendées ou non (“non” signifie qu’elles ne sont plus assez sécurisées par rapport aux standards actuels). A l’heure où cet article est rédigé (Q4 2019), les cipher suites valides sont :

TLS_DHE_RSA_WITH_AES_128_GCM_SHA256
TLS_DHE_RSA_WITH_AES_256_GCM_SHA384
TLS_DHE_PSK_WITH_AES_128_GCM_SHA256
TLS_DHE_PSK_WITH_AES_256_GCM_SHA384
TLS_AES_128_GCM_SHA256
TLS_AES_256_GCM_SHA384
TLS_CHACHA20_POLY1305_SHA256
TLS_AES_128_CCM_SHA256
TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256
TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384
TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256
TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384
TLS_DHE_RSA_WITH_AES_128_CCM
TLS_DHE_RSA_WITH_AES_256_CCM
TLS_DHE_PSK_WITH_AES_128_CCM
TLS_DHE_PSK_WITH_AES_256_CCM
TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256
TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256
TLS_DHE_RSA_WITH_CHACHA20_POLY1305_SHA256
TLS_ECDHE_PSK_WITH_CHACHA20_POLY1305_SHA256
TLS_DHE_PSK_WITH_CHACHA20_POLY1305_SHA256
TLS_ECDHE_PSK_WITH_AES_128_GCM_SHA256
TLS_ECDHE_PSK_WITH_AES_256_GCM_SHA384
TLS_ECDHE_PSK_WITH_AES_128_CCM_SHA256

CHACHA20 est un algorithme de chiffrement standardisé récemment pour avoir une roue de secours si AES venait à être percé (il était devenu trop omniprésent).

Les versions du protocoles

Ces Cipher Suite sont utilisées par les protocoles SSL/TLS. Il en existe 6 versions utilisables :

  • SSLv2
  • SSLv3
  • TLSv1.0
  • TLSv1.1
  • TLSv1.2
  • TLSv1.3
Le protocole va fixer comment on utilise les ciphersuite mais aussi plein d’autres actions autour:
  • s’accorder entre le serveur et le client sur quelle ciphersuite utiliser
  • s’occuper de comment compresser les paquets
  • comment on gère le padding
  • la gestion des erreurs
  • etc.
De votre côté, comme dit Barney Stinson:
Private key encryption

En gros on sort une nouvelle version quand la précédente ne répond plus à tous les prérequis de la sécurité. Donc il faut toujours avoir au moins la dernière.
Ensuite on active ou pas des plus anciennes selon que ceux qui vont se connecter à votre site utilisent des navigateurs de l’age de pierre ou non.
Le problème c’est qu’en autorisant d’anciennes versions on s’expose à des vulnérabilités. Certaines peuvent être jugulées en activant des options spécifiques (nous y reviendrons), mais ce n’est jamais idéal. Et pour SSLv2 ce serait même catastrophique (nous y reviendrons aussi).

Donc votre sujet c’est de savoir avec quel navigateur se pointent vos visiteurs. Pour cela, je n’ai pas trouvé de bible plus complète que celle de Wikipedia: https://en.wikipedia.org/wiki/Transport_Layer_Security_Adoption.
On peut donc déduire du mega tableau de cette brillante page la matrice de support suivante :

SSLv3 TLSv1.0 TLSv1.1 TLSv1.2 TLSv1.3
IE/Edge v4 v7 v11 v11 X
Firefox v1 v1 v27 v27 v63
Chrome v1 v1 v22 v30 v70
Safari v1 v1 v7 v7 v12
Opera v4 v5 v12.18 v12.18 v57
Android v1 v1 v5 v5 X
iOS v1 v1 v5 v5 v12

Donc en gros il n’y a aucune bonne raison d’autoriser SSLv3 si vos clients ont au moins IE7 (qui date de Windows XP) puisqu’ils peuvent utiliser TLSv1.0. Et d’aventure ces utilisateurs auraient un sérieux problème à naviguer sur Internet avec un XP.
Désactiver TLSv1.0 se fait assez bien aussi puisque les utilisateurs de Windows 7 peuvent dialoguer en TLSv1.1.
Vous remarquerez que la plupart des navigateurs ont activé TLSv1.1 et v1.2 dans la même version. En fait, TLSv1.1 était souvent implémenté depuis plus longtemps mais pas activé par défaut. En somme, quand vous pouvez désactiver TLSv1.0, vous pouvez très souvent aussi désactiver TLSv1.1 car TLSv1.2 est aussi supporté.
Une des options importantes quand on autorise des vieilles versions c’est le cipherorder qui consiste à ce que le serveur impose l’ordre des cipher suite. Cela évite que si le client et le serveurs discutent avec un vieux protocole alors qu’ils supportent tous les deux des versions plus récentes (ce que les pirates cherchent à produire dans les protocol downgrade).

L’implémentation des protocoles

Maintenant que nous avons vu toutes les parties “théoriques” : les algorithmes, les RFC, etc. intéressons-nous aux bibliothèques logicielles qui les implémentent.
Pour n’en citer que quelques unes :

  • OpenSSL
  • GnuTLS
  • LibreSSL
  • Bouncy Castle
  • JSSE (pour Java)
  • BoringSSL (par Google)
  • Network Security Services (NSS), co-développé par AOL, Red Hat, Sun Microsystems/Oracle, Google et Mozilla. Utilisé par Firefox, Opéra, Red Hat Directory Server, …
  • Security Transport (par Apple)
  • Schannel (par Microsoft)

Il se peut très bien que vous utilisiez un algorithme robuste, une bonne cipher suite, la bonne version du protocole mais que la personne qui l’a implémenté ait été douée de deux mains gauches.
Quand un développeur va transcrire une RFC dans le language informatique de son choix (C, C++, python, Java, etc.) il va devoir faire des choix techniques quant à la représentation des données en mémoire, leur stockage, leur affectation, etc. Autant de domaines où il peut introduire des vulnérabilités s’il n’est pas attentif.
Et ça s’est déjà produit. Certaines implémentations ne respectaient pas suffisamment les RFC (les normes) des algorithmes qu’elles utilisaient (libertés prises par rapport au standard, mésinterprétations conduisant par exemple à des padding oracle), d’autres n’utilisaient pas les fonctions de leur langage de manière sécurisée (buffer overflow, etc…).

Comment donc éviter ces erreurs ? En amont la plupart des RFC des chiffrements modernes incluent des conseils pour les développeurs afin d’éviter ces écueils.
En aval, des organismes certifient ces bibliothèques. La certification la plus pertinente demeure encore probablement FIPS-140 (standard d’exigences produit par le National Institute of Standards and Technology (NIST) pour le gouvernement des Etats-Unis). Mais de là à dire qu’une implémentation certifiée FIPS-140 peut être utilisée les yeux fermés… il y a un monde.

Bien, me direz-vous, c’est bien joli, mais qu’est-ce qu’on choisit alors ? Premièrement, il n’y a pas de réponse absolue. Donc je vais vous répondre, mais ce sera en partie subjectif. Mais d’abord, un peu d’Histoire …

En 1995 démarrait SSLeay, une première implémentation Open Source du protocole SSLv3. Après quelques années, les fondateurs stoppent leur travail qui est forké pour donner, en 1998, OpenSSL. Il s’agit de l’implémentation la plus connue et la plus répandue. Elle est écrite en C, assembleur et Perl et fonctionne pour Unix (Linux, Mac) et Windows.

Aujourd’hui, quand vous déployez un site Web, vous êtes très majoritairement sur une base Linux. Que vous utilisiez Apache, Nginx ou autre, c’est encore quasiment exclusivement OpenSSL qui est utilisé pour gérer la partie SSL/TLS.
Mais rien ne dit que cela perdure longtemps.

Dans le monde de la sécurité, il y a eu un petit séïsme en 2014 avec la vulnérabilité heartbleed qui a touché OpenSSL. On redécouvre alors cette brique qui s’était faite oubliée. La majorité de son code date de plusieurs années (avant que les développeurs soient largement sensibilisés à la sécurité) et certains commencent à se dire qu’hearbleed n’est peut être que la partie émergée de l’iceberg.
Notamment la team OpenBSD regarde alors de plus près le code source et décide qu’il faut forker le projet. Pour vous présenter rapidememnt cette équipe, c’est elle qui développe le système d’exploitation probablement le plus “security oriented” qui existe. Ils sont ultra exigeants sur la qualité du code qu’ils produisent. C’est notamment eux qui sont à l’origine de l’implémentation de SSH omniprésente : OpenSSH (car personne ne veut prendre de risque avec un outil aussi critique). Donc quand ces mecs disent un truc, on les écoute.
Bref, ils créent le fork LibreSSL. En une semaine ils vont virer 90 000 lignes de code inutile selon eux (la minimisation est une des meilleures voies vers la sécurité).
En termes donc de réputation, LibreSSL se pose bien : léger et fiable (d’ailleurs adopté par Alpine Linux).

Mais l’actualité de SSL/TLS a plus d’un rebondissement. Plus récemment (2019), une implémentation peu connue a fait parler d’elle : Rustls link (prononcez “rustles”). Cette implémentation est donc écrite en Rust, langage réputé pour permettre la capacité d’écrire du code bas niveau sans risque de corruption de la mémoire (comme en C/C++). Je ne prétends pas avoir les compétences pour dire si c’est une réputation usurpée ou non mais ça a été fait par Mozilla (à qui je voue une confiance certaine).
Il se trouve que Rustls a un peu explosé OpenSSL dans un test de perfomances link (…mené par le créateur de Rustls bon hum…) : 15 % plus rapide pour envoyer des données, 20 à 40 % plus rapide pour configurer une connexion client, 30 à 70 % plus rapide pour reprendre une connexion client, utilise moins de la moitié de la mémoire de OpenSSL, …
En termes d’héritage, la team OpenBSD n’a pas été la seule à forker OpenSSL après Heartbleed, Google aussi l’a fait avec BoringSSL (et Google n’est pas vraiment une brebis galeuse en sécurité). Ring est un portage en Rust de BoringSSL et Rustls se base sur Ring (et y ajoute la gestion des certificats).

Pour résumer, OpenSSL reste la solution facile à privilégier si vous n’avez pas envie de jouer au héro (pléthore de tuto). LibreSSL est l’outsider, léger et probablement plus sécurisé. Enfin Rustls est l’étoile montante pour les early adopter.

Les certificats

Bien nous avons fini de parler de la pile SSL/TLS mais il reste un sujet peu exploré : les certificats, qui, pourquoi, qui les financent, quels sont leurs projets secrets ?

Si vous vous rappelez un peu ce que l’on a dit sur les algorithmes de chiffrement, les algorithmes asymétriques permettent de partager un secret sur un canal non sûr. Pour envoyer un message chiffré à un tiers, il suffit d’utiliser sa clé publique (son certificat) qui n’est pas un secret.
Seulement, il y a toujours le risque d’une usurpation quand nous récupérons ce certificat (à ce moment la communication n’est pas encore protégée). Il serait dommage que nous envoyions notre secret à la mauvaise personne (qui aurait remplacé le certificat légitime par le sien).

Pour cela, un certificat doit être signé numériquement par une autorité de confiance (qu’on nomme autorité de certification : AC ou CA en anglais).
De cette façon, quand nous recevons un certificat, si quelqu’un s’est amusé à en substituer un faux, la vérification de la signature échoue.
Il serait trop technique de détailler le mécanisme de signature, sachez juste qu’aujourd’hui on sait produire une signature numérique de telle sorte qu’une seule personne puisse la forger (l’autorité de confiance) mais que tout le monde puisse la vérifier. Et la “vérifier” signifie d’effectuer quelques opérations simples qui permettent d’avoir la certitude que le contenu que l’on consulte est rigoureusement identique à celui qui a été signée par l’autorité de confiance.

Donc si je reçois un certificat de la part de Julian A, que ce certificat est signé par l’autorité de confiance WikiL, en vérifiant la signature j’aurais une erreur si :

  • quelqu’un a émis un faux certificat au nom de Julian A en y reapposant la signature WikiL du certificat authentique
  • quelqu’un a substitué un certificat à un autre nom que Julian A (par exemple George B) mais correctement signé par WikiL
  • quelqu’un a émis un faux certificat au nom de Julian A en y apposant une autre signature que celle de WikiL
  • quelqu’un a émis un faux certificat au nom de Julian A sans y apposer de signature
  • quelqu’un a modifié le certificat originel de Julian A
  • etc.
De quoi a-t-on besoin pour vérifier une signature ? De la clé publique (le certificat) de l’autorité de confiance.
… La normalement vous vous dites “de quoi ? mais la signature on a dit que ça servait pour vérifier les certificats, s’il faut un certificat pour le faire, c’est le serpent qui se mord la queue”.

Auquel cas vous avez bien compris ce qu’on a dit jusqu’ici.
Pour palier à ce problème, on a rien trouvé de mieux que de pré-embarquer dans chaque ordinateur les certificats d’environ 500 autorités de certification (qu’on nomme autorités de certification racines). C’est pas élégant mais c’est efficace.
Dans votre Linux, votre Mac ou votre Windows, il y a un dossier avec tous ces certificats (/etc/ssl/certs sous Linux le plus souvent). Du coup pas besoin de télécharger le certificat d’une autorité de confiance via un canal non sûr, le certificat est déjà chez vous. On peut donc s’en servir pour vérifier les signatures de tous les autres certificats qu’elle a signés.

Je mentionne juste au passage la notion de pinning qui permet à un site de dire quelles autorités sont légitimes à produire un certificat pour ce site. Car si une seule des AC racines venait à être compromise, l’attaquant pourrait forger des certificats pour n’importe quel site (Google, la NSA, etc.) qui seraient tous reconnus comme valides.

Comment obtient-on un certificat X509 ?

Vous pouvez vous créer vous-même votre certificat avec des outils en ligne de commande intégrés dans Linux (comme openssl) ou plus graphiques comme XCA. Comme mémo des commandes openssl, j’utilise généralement ce lien : https://www.digitalocean.com/community/tutorials/openssl-essentials-working-with-ssl-certificates-private-keys-and-csrs et pour XCA vous pouvez suivre celui-ci : https://collilieux.net/doc/xca.

Dans l’ordre, vous créez un bi-clé (clé publique + clé privée). Vous créez un fichier CSR (certificate signing request) et vous l’envoyez à l’autorité de certification dont vous souhaitez qu’elle tamponne votre certificat de son sceau (qu’elle appose sa signature numérique).
Cela peut être :

  • Une autorité de certification que vous avez vous-même créée (si votre certificat est destiné à être utilisé uniquement dans un périmètre que vous contrôlez).
  • Une autorité de votre entreprise (si votre certificat est destiné à être utilisé uniquement au sein de l’entité à laquelle vous appartenez).
  • Une autorité de certification commerciale (si votre certificat est destiné à être utilisé sur tout Internet).
    Dans ce dernier cas, il faudra le plus souvent payer.
Un seul acteur est complétement gratuit : Let’s Encrypt.
Le mode opératoire est intéressant, il s’agit le plus souvent d’un outil sur votre serveur qui va rendre une certaine chaine de caractère (un challenge) accessible sur votre site en HTTP. Si le serveur de let’s encrypt arrive à joindre ce challenge à l’adresse que vous avez déclarée, il permettra à l’outil de générer le bi-clé et signera la clé publique (donc la clé privée est générée sur votre serveur et n’est pas connue de let’s encrypt). Dès lors, vous aurez tout le nécessaire pour passer votre site de HTTP vers HTTPS.
Pour être guidé dans cette opération, vous pouvez suivre ce lien : https://certbot.eff.org
C’est personnellement ce que j’utilise. Le seul bémol c’est que la durée de validité est limitée à 3 mois (au lieu d’un ou deux ans pour les autorités de certification payantes).

Si vous recourez à une autorité de certification commerciale, vous aurez généralement la possibilité de n’avoir rien à faire, ils génèrent et vous livrent tout le package (clé publique, clé privée). Donc pas besoin de générer le bi-clé et le CSR de votre côté, en contre-partie, cette autorité connait votre clé privée (ce qui n’est pas complétement dramatique pour un certificat de serveur Web mais à éviter si possible).

Concernant le certificat que vous allez déployer sur votre serveur, il y a 5 points de sécurité à vérifier :

Le CN (CommonName)

C’est le champ dans la partie “subject” qui détermine pour quel périmètre votre certificat est valide.
Si votre site c’est www.refaitesgotsaison8.org il faut que le commonName soit www.refaitesgotsaison8.org ou *.refaitesgotsaison8.org.
Dans ce second cas (que l’on nomme un certificat wildcard), vous pourrez utiliser ce même certificat aussi bien pour wwww.refaitesgotsaison8.org que pour mail.refaitesgotsaison8.org ou ns.refaitesgotsaison8.org ou encore blabla.lespingouins.refaitesgotsaison8.org.
Les certificats wildcard sont plus chers (sauf sur Lets encrypt où c’est toujours gratuit mais un chouilla plus long à mettre en place).

Si vous ne renseignez pas le bon commonName pour votre site, les navigateurs lèveront une erreur aux éventuels visiteurs :

CN

L’algorithme de signature

Votre certificat X509 est la partie clé publique de votre bi-clé, celle qui permet à tout le monde de créer des messages chiffrés que seul vous pourrez déchiffrer (avec votre clé privée). Et c’est aussi elle qui permet à tout le monde de vérifier des signatures que vous avez produites. Elle indique donc comment le message doit être chiffré pour que vous puissiez le déchiffrer et comment la signature doit être vérifiée, donc quels algorithmes sont impliqués.
C’est généralement indiqué sous la forme sha1WithRSAEncryption ou sha256WithRSAEncryption. SHA-1 n’est plus considéré comme suffisamment sûr pour la signature numérique, donc assurez-vous que c’est bien sha256WithRSAEncryption sinon vos utilisateurs risquent d’avoir une alerte de “WEAK SIGNATURE ALGORITHM” :

Signature

La date d’expiration

Les certificats sont toujours émis avec une date d’expiration. Notamment car l’autorité qui signe votre certificat ne sait pas combien de temps vous allez garder votre nom de domaine (si vous le vendez mais que vous conservez un certificat valide c’est problématique). Mais aussi car les attaques et les puissances de calcul évoluent et qu’il faut donc régénérer des certificats avec les derniers paramètres à jour régulièrement.
Avec let’s encrypt, vous pouvez mettre en tâche cron de relancer l’outil certbot qui renouvelle vos certificats automatiquement. Si vous êtes passé par une autorité de certification commerciale, il faut vous mettre un reminder quelque part pour penser à renouveler le certificat ! Bon généralement l’autorité qui vous l’a délivré vous envoie un petit mail quand le certificat va expirer (mais ce n’est pas une bonne idée de ne compter que sur ça).
Si vous vous faites prendre de court, vos utilisateurs verront une erreur du type :

Expiration

L’issuer

Le champ “issuer” désigne l’entité qui émet le certificat. Tant que votre certificat n’est pas signé, l’issuer c’est votre propre certificat (on dit alors qu’il est auto-signé). Quand vous faites signer votre certificat par une autorité de certification, c’est elle qui devient l’issuer.
Il est nécessaire que l’issuer soit une entité reconnue par les utilisateurs qui visiteront votre site. Si votre certificat est signé par une autorité sous votre contrôle (par exemple une AC d’entreprise), ça marchera bien si vous installez le certificat de cette AC sur les machines des utilisateurs (à côté des AC commerciales préinstallées sur toutes les machines).

Quand le certificat est auto-signé ou signé par une autorité inconnue du client, il verra une erreur du type :

Issuer

Les droits de la clé privée

Dernier petit détail qu’on oublie souvent : la clé privée est privée. Donc il faut bien la protéger. Au niveau de ses droits, il est donc fortement recommandé de lui octroyer uniquement les droits en lecture user (chmod 400).
Inversement si une de vos machines est un jour compromise, il faudra changer les éventuels certificats utilisés (puisque l’attaquant aura probablement eu accès aux clés privées) et demander à votre autorité de certification de les révoquer (à fortiori si vous utilisez un certificat wildcard). Sinon l’attaquant pourrait monter des interceptions (Man in The Middle) et observer du trafic sensible normalement chiffré.

Configurer TLS

Avant de vous expliquer comment on va configurer SSL/TLS sur notre serveur, il peut être utile de faire une brève liste des vulnérabilités spécifiques (jusqu’ici nous avons vu les erreurs d’ordre général) que l’on chercher à éviter.

Les attaques contre TLS

Nous serons ici bref pour chaque cas. Ces vulnérabilités peuvent avoir touché les protocoles (et donc toutes les implémentations qui ont scrupuleusement suivi les RFC) ou seulement les implémentations (le plus souvent OpenSSL).
La liste n’est pas exhaustive mais l’IETF a gentillement produit une RFC rassemblant les attaques connues à ce jour: RFC 7457, référez-vous y en cas de besoin.

  • SSL Stripping
    C’est le fait d’empêcher un site de passer du simple HTTP au HTTPS. En général c’est implémenté côté serveur en configurant une redirection 301 du style return 301 https://www.astar.org$request_uri;. Si je suis en position d’interception, je peux à ce moment là moi-même discuter en TLS avec le serveur et servir une version toujours en HTTP à la victime. Je peux aussi réécrire tous les liens d’une page qui sont en https://quelquechose en http://quelquechose à la volée. Dans ce dernier cas, le HSTS (HTTP Strict Transport Security) permet de s’en prémunir.
  • BEAST
    Vulnérabilité de SSLv3 et TLSv1.0 qui utilisaient mal les modes de chiffrement symétriques CBC et pouvait permettre de retrouver une partie des données chiffrées.
  • LUCKY13
    Il s’agit d’une timing attack (on peut déduire certaines données en se basant sur le temps de traitement) contre le mode de chiffrement CBC. Pour le coup, c’est inhérent à ce mode et ça ne dépend pas de la version de TLS. Donc la réponse principale c’est d’utiliser le mode GCM à la place.
  • POODLE
    Attaque du type Padding Oracle contre des mauvaises implémentations du mode CBC (décidément). Il suffit normalement d’avoir une version à jour de votre implémentation de TLS pour corriger.
  • RC4
    En gros, on a commencé à trouver de plus en plus de problèmes dans le chiffrement symétrique RC4 de sorte qu’il fallait vraiment arrêter de l’utiliser. Bon c’est pas le premier à qui ça arrive mais c’était drôle car ceux qui voulaient corriger les failles BEAST, LUCKY13, etc., sans monter en version TLS, désactivaient les chiffrements CBC et utilisaient RC4 à la place… ben là ils étaient marrons.
  • CRIME
    Défaut dans la compression au niveau de la couche TLS qui pouvait révéler des portions du message chiffré.
  • BREACH
    Pareil mais pour la compression au niveau de la couche HTTP. Pour celle-ci comme pour CRIME, il n’est pas extrêmement clair de savoir si c’est corrigé ou non. Depuis un moment, le consensus est de dire : n’activez plus la compression du tout
  • Logjam
    Beaucoup de configurations autorisaient encore un algorithme d’échange de clés en 1024 bits (voir 512) au lieu de 2048. Un moyen a été trouvé dans TLS pour forcer une communication à utiliser ces vieilles versions au lieu des nouvelles. Donc voila on a tout banni dans les vieux trucs.
  • FREAK
    Pareil mais pour un autre algo asymétrique (RSA).
  • ROBOT
    Un problème dans la gestion du padding de RSA permettait de révéler des informations chiffrées. Il semblerait que les contre-mesures soient si complexes à implémenter que le mieux reste de se passer de RSA pour l’échange de clés.
  • Heartbleed
    OpenSSL implémentait mal la fonction heartbeat du protocole TLS. Il en résultat qu’on pouvait faire en sorte que le serveur distant nous révèle une partie de sa RAM (pouvant contenir des mots de passe ou autres informations tendax). Donc vraiment un problème sérieux.
  • BERserk
    NSS gérait mal certains encodages ce qui pouvait amener à valider des signatures pourtant incorrectes.
  • ChangeCipherSpec injection
    OpenSSL gérait mal les demandes de changement de cipher de sorte qu’un attaquant pouvait forcer une communication à utiliser de vieux algorithmes moisis (et donc retrouver le contenu en clair s’il pouvait intercepter la communication). Cette faille s’inscrit dans la catégorie (assez peuplée) des protocol downgrade où l’attaquant cherche à ce que la communication utilise des protocoles qu’il sait casser. D’où le fait qu’il n’est pas suffisant d’autoriser les dernières versions, il faut aussi révoquer les vieilles.
  • SWEAT32 Concerne les chiffrements par bloc qui utilisent des blocs de trop petite taille. Dans des conditions difficilement crédibles, certaines données chiffrées pourraient être révélées. Donc on décourage maintenant l’usage de Blowfish et TripleDES.
  • DROWN
    Il était possible de déchiffrer des données sécurisées avec les meilleurs protocoles si à côté de ça SSLv2 était toujours autorisé (même si c’était sur un autre serveur utilisant le même certificat).

Vous verrez que plusieurs failles ont leur petit nom et leur petit site Web.
Ceux qui les découvrent sont souvent prompts à dire que c’est grave mais, souvent, les conditions pour les reproduire sont tellement improbables que ça n’interesse aucun pirate (éventuellement les agences de renseignement étatiques).
Heartbleed a probablement été la plus dangereuse.

Produire une configuration TLS sécurisée

C’en est enfin terminé de la partie explication. Je vous ai expliqué les pièges qu’il faut éviter, maintenant voyons comment les éviter.
Nous partons ici du principe que vous chercher à utiliser SSL/TLS pour un site Web, donc pour un serveur Apache, Nginx, IIS, etc.

Je pourrais vous coller ici une conf aux petits oignons pour chaque serveur, mais il faudrait que je mette à jour cet article tous les 3 mois.
Je vais plutôt vous donner la liste des ressources que j’utilise pour configurer mes serveurs SSL/TLS de manière propre. Et comme ces sites se mettent à jour de leur côté, ce sera plus simple.

Mon favori est probablement cypherlist link . Il est très strict sur la sécurité et propose des configurations pour à peu près tout ce qui existe… mais sur Linux, donc rien sur IIS. Normalement avec celui-là vous avez votre A+ sur SSLLabs.

Le second que j’aimerais présenter est bettercrypto link . Il a l’avantage d’inclure des configurations pour presque tout DONT IIS. Mais il est un peu moins strict que cipherli.st. Peut être n’aurez-vous pas toujours les A+.

Le dernier est intéressant lorsque vous avez besoin de faire une configuration rétro-compatible mais aussi sécurisée que possible: ssl-config de Mozilla link . Il y a presque tout sauf IIS (nan mais sérieusement c’est pas grave en fait, personne n’utilise ça par choix). Et donc vous pouvez choisir si vous voulez une configuration moderne (aussi sécurisée que possible), intermédiaire (qui est compatible avec des clients qui ne sont pas bleeding edge mais qui sont quand même encore utilisés) ou vieille (donc la on se rend compatible avec les dinosaures).

Tester son TLS

Comment vérifier maintenant que votre configuration SSL/TLS déployée est bonne. Il y a évidemment le très célèbre ssllabs link de Qualys. Mais ce n’est pas la seule chose intéressante.
Notamment si vous voulez tester des sites que vous hébergez en interne et que le Lab SSL ne peut joindre. Pour ces cas là, on utilisera des outils en ligne de commande.
J’utilise pour ma part testssl.sh link quand je veux être sûr de ne rien louper, notamment car il me donne les longueurs de clé des cipher suite. Il s’utilise assez simplement car, de base, il met toutes les options utiles (ajoutez un -E si vous voulez les cipher suite par version de SSL/TLS) :

$ ./testssl.sh www.astar.org

###########################################################
    testssl.sh       3.0rc4 from https://testssl.sh/dev/
    (9eec4db 2019-07-20 10:07:10 -- )

      This program is free software. Distribution and
             modification under GPLv2 permitted.
      USAGE w/o ANY WARRANTY. USE IT AT YOUR OWN RISK!

       Please file bugs @ https://testssl.sh/bugs/

###########################################################

 Using "OpenSSL 1.0.2-chacha (1.0.2k-dev)" [~179 ciphers]
 on vane:./bin/openssl.Linux.x86_64
 (built: "Jan 18 17:12:17 2019", platform: "linux-x86_64")

 Start 2019-12-21 17:25:33        -->> 163.172.157.89:443 (www.astar.org) <<--

 rDNS (163.172.157.89):  89-157-172-163.rev.cloud.scaleway.com.
 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    not offered
 NPN/SPDY   h2, http/1.1 (advertised)
 ALPN/HTTP2 h2, http/1.1 (offered)

 Testing cipher categories 

 NULL ciphers (no encryption)                  not offered (OK)
 Anonymous NULL Ciphers (no authentication)    not offered (OK)
 Export ciphers (w/o ADH+NULL)                 not offered (OK)
 LOW: 64 Bit + DES, RC[2,4] (w/o export)       not offered (OK)
 Triple DES Ciphers / IDEA                     not offered (OK)
 Average: SEED + 128+256 Bit CBC ciphers       offered
 Strong encryption (AEAD ciphers)              offered (OK)


 Testing robust (perfect) forward secrecy, (P)FS -- omitting Null Authentication/Encryption, 3DES, RC4 

 PFS is offered (OK)          ECDHE-RSA-AES256-GCM-SHA384 ECDHE-RSA-AES256-SHA384 ECDHE-RSA-AES256-SHA DHE-RSA-AES256-GCM-SHA384 DHE-RSA-AES256-SHA256 DHE-RSA-AES256-SHA ECDHE-RSA-AES128-GCM-SHA256
                              DHE-RSA-AES128-GCM-SHA256 
 Elliptic curves offered:     secp384r1 
 DH group offered:            Unknown DH group (4096 bits)

 Testing server preferences 

 Has server cipher order?     yes (OK)
 Negotiated protocol          TLSv1.2
 Negotiated cipher            ECDHE-RSA-AES256-GCM-SHA384, 384 bit ECDH (P-384)
 Cipher order
    TLSv1.2:   ECDHE-RSA-AES256-GCM-SHA384 ECDHE-RSA-AES128-GCM-SHA256 DHE-RSA-AES256-GCM-SHA384 DHE-RSA-AES128-GCM-SHA256 ECDHE-RSA-AES256-SHA384 ECDHE-RSA-AES256-SHA DHE-RSA-AES256-SHA256
               DHE-RSA-AES256-SHA 


 Testing server defaults (Server Hello) 

 TLS extensions (standard)    "server name/#0" "renegotiation info/#65281" "EC point formats/#11" "status request/#5" "heartbeat/#15" "next protocol/#13172" "application layer protocol negotiation/#16"
 Session Ticket RFC 5077 hint no -- no lifetime advertised
 SSL Session ID support       yes
 Session Resumption           Tickets no, ID: yes
 TLS clock skew               Random values, no fingerprinting possible 
 Signature Algorithm          SHA256 with RSA
 Server key size              RSA 2048 bits
 Server key usage             Digital Signature, Key Encipherment
 Server extended key usage    TLS Web Server Authentication, TLS Web Client Authentication
 Serial / Fingerprints        04765B9A17E454A611412FB327842F1C4D2C / SHA1 D20FCDAAB1456FE8FC93197BB05B4B711A4D4963
                              SHA256 5C6799850EFDEAC7DBCF7B7C356E9D9599626AABD5740C9D9AC012C6A372DE0F
 Common Name (CN)             www.astar.org
 subjectAltName (SAN)         bonny.astar.org inglorious.astar.org www.astar.org 
 Issuer                       Let's Encrypt Authority X3 (Let's Encrypt from US)
 Trust (hostname)             Ok via SAN and CN (same w/o SNI)
 Chain of trust               Ok   
 EV cert (experimental)       no 
 "eTLS" (visibility info)     not present
 Certificate Validity (UTC)   71 >= 30 days (2019-12-03 03:55 --> 2020-03-02 03:55)
 # of certificates provided   2
 Certificate Revocation List  --
 OCSP URI                     http://ocsp.int-x3.letsencrypt.org
 OCSP stapling                offered, not revoked
 OCSP must staple extension   --
 DNS CAA RR (experimental)    not offered
 Certificate Transparency     yes (certificate extension)


 Testing HTTP header response @ "/" 

 HTTP Status Code             200 OK
 HTTP clock skew              -22 sec from localtime
 Strict Transport Security    not offered
 Public Key Pinning           --
 Server banner                nginx/1.10.3 (Ubuntu)
 Application banner           --
 Cookie(s)                    2 issued: NONE secure, 1/2 HttpOnly
 Security headers             X-Frame-Options DENY
                              X-XSS-Protection 1; mode=block
                              X-Content-Type-Options nosniff
 Reverse Proxy banner         --


 Testing vulnerabilities 

 Heartbleed (CVE-2014-0160)                not vulnerable (OK), timed out
 CCS (CVE-2014-0224)                       not vulnerable (OK)
 Ticketbleed (CVE-2016-9244), experiment.  not vulnerable (OK), no session ticket extension
 ROBOT                                     Server does not support any cipher suites that use RSA key transport
 Secure Renegotiation (CVE-2009-3555)      not vulnerable (OK)
 Secure Client-Initiated Renegotiation     not vulnerable (OK)
 CRIME, TLS (CVE-2012-4929)                not vulnerable (OK)
 BREACH (CVE-2013-3587)                    potentially NOT ok, uses gzip HTTP compression. - only supplied "/" tested
                                           Can be ignored for static pages or if no secrets in the page
 POODLE, SSL (CVE-2014-3566)               not vulnerable (OK)
 TLS_FALLBACK_SCSV (RFC 7507)              No fallback possible, no protocol below TLS 1.2 offered (OK)
 SWEET32 (CVE-2016-2183, CVE-2016-6329)    not vulnerable (OK)
 FREAK (CVE-2015-0204)                     not vulnerable (OK)
 DROWN (CVE-2016-0800, CVE-2016-0703)      not vulnerable on this host and port (OK)
                                           make sure you don't use this certificate elsewhere with SSLv2 enabled services
                                           https://censys.io/ipv4?q=5C6799850EFDEAC7DBCF7B7C356E9D9599626AABD5740C9D9AC012C6A372DE0F could help you to find out
 LOGJAM (CVE-2015-4000), experimental      not vulnerable (OK): no DH EXPORT ciphers, no common prime detected
 BEAST (CVE-2011-3389)                     no SSL3 or TLS1 (OK)
 LUCKY13 (CVE-2013-0169), experimental     potentially VULNERABLE, uses cipher block chaining (CBC) ciphers with TLS. Check patches
 RC4 (CVE-2013-2566, CVE-2015-2808)        no RC4 ciphers detected (OK)

 Testing 370 ciphers via OpenSSL plus sockets against the server, ordered by encryption strength 

Hexcode  Cipher Suite Name (OpenSSL)       KeyExch.   Encryption  Bits     Cipher Suite Name (IANA/RFC)
-----------------------------------------------------------------------------------------------------------------------------
 xc030   ECDHE-RSA-AES256-GCM-SHA384       ECDH 384   AESGCM      256      TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384              
 xc028   ECDHE-RSA-AES256-SHA384           ECDH 384   AES         256      TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384              
 xc014   ECDHE-RSA-AES256-SHA              ECDH 384   AES         256      TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA                 
 x9f     DHE-RSA-AES256-GCM-SHA384         DH 4096    AESGCM      256      TLS_DHE_RSA_WITH_AES_256_GCM_SHA384                
 x6b     DHE-RSA-AES256-SHA256             DH 4096    AES         256      TLS_DHE_RSA_WITH_AES_256_CBC_SHA256                
 x39     DHE-RSA-AES256-SHA                DH 4096    AES         256      TLS_DHE_RSA_WITH_AES_256_CBC_SHA                   
 xc02f   ECDHE-RSA-AES128-GCM-SHA256       ECDH 384   AESGCM      128      TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256              
 x9e     DHE-RSA-AES128-GCM-SHA256         DH 4096    AESGCM      128      TLS_DHE_RSA_WITH_AES_128_GCM_SHA256                


 Running client simulations (HTTP) via sockets 

 Android 4.2.2                No connection
 Android 4.4.2                TLSv1.2 ECDHE-RSA-AES256-GCM-SHA384, 384 bit ECDH (P-384)
 Android 5.0.0                TLSv1.2 ECDHE-RSA-AES128-GCM-SHA256, 384 bit ECDH (P-384)
 Android 6.0                  TLSv1.2 ECDHE-RSA-AES128-GCM-SHA256, 384 bit ECDH (P-384)
 Android 7.0                  TLSv1.2 ECDHE-RSA-AES256-GCM-SHA384, 384 bit ECDH (P-384)
 Android 8.1 (native)         TLSv1.2 ECDHE-RSA-AES256-GCM-SHA384, 384 bit ECDH (P-384)
 Android 9.0 (native)         TLSv1.2 ECDHE-RSA-AES256-GCM-SHA384, 384 bit ECDH (P-384)
 Chrome 65 Win 7              TLSv1.2 ECDHE-RSA-AES256-GCM-SHA384, 384 bit ECDH (P-384)
 Chrome 73 (Win 10)           TLSv1.2 ECDHE-RSA-AES256-GCM-SHA384, 384 bit ECDH (P-384)
 Firefox 62 Win 7             TLSv1.2 ECDHE-RSA-AES256-GCM-SHA384, 384 bit ECDH (P-384)
 Firefox 66 (Win 8.1/10)      TLSv1.2 ECDHE-RSA-AES256-GCM-SHA384, 384 bit ECDH (P-384)
 IE 6 XP                      No connection
 IE 7 Vista                   No connection
 IE 8 Win 7                   No connection
 IE 8 XP                      No connection
 IE 11 Win 7                  TLSv1.2 DHE-RSA-AES256-GCM-SHA384, 4096 bit DH  
 IE 11 Win 8.1                TLSv1.2 DHE-RSA-AES256-GCM-SHA384, 4096 bit DH  
 IE 11 Win Phone 8.1          TLSv1.2 ECDHE-RSA-AES256-SHA, 384 bit ECDH (P-384)
 IE 11 Win 10                 TLSv1.2 ECDHE-RSA-AES256-GCM-SHA384, 384 bit ECDH (P-384)
 Edge 15 Win 10               TLSv1.2 ECDHE-RSA-AES256-GCM-SHA384, 384 bit ECDH (P-384)
 Edge 17 (Win 10)             TLSv1.2 ECDHE-RSA-AES256-GCM-SHA384, 384 bit ECDH (P-384)
 Opera 60 (Win 10)            TLSv1.2 ECDHE-RSA-AES256-GCM-SHA384, 384 bit ECDH (P-384)
 Safari 9 iOS 9               TLSv1.2 ECDHE-RSA-AES256-GCM-SHA384, 384 bit ECDH (P-384)
 Safari 9 OS X 10.11          TLSv1.2 ECDHE-RSA-AES256-GCM-SHA384, 384 bit ECDH (P-384)
 Safari 10 OS X 10.12         TLSv1.2 ECDHE-RSA-AES256-GCM-SHA384, 384 bit ECDH (P-384)
 Apple ATS 9 iOS 9            TLSv1.2 ECDHE-RSA-AES256-GCM-SHA384, 384 bit ECDH (P-384)
 Tor 17.0.9 Win 7             No connection
 Java 6u45                    No connection
 Java 7u25                    No connection
 Java 8u161                   TLSv1.2 ECDHE-RSA-AES256-GCM-SHA384, 384 bit ECDH (P-384)
 Java 9.0.4                   TLSv1.2 ECDHE-RSA-AES256-GCM-SHA384, 384 bit ECDH (P-384)
 OpenSSL 1.0.1l               TLSv1.2 ECDHE-RSA-AES256-GCM-SHA384, 384 bit ECDH (P-384)
 OpenSSL 1.0.2e               TLSv1.2 ECDHE-RSA-AES256-GCM-SHA384, 384 bit ECDH (P-384)
 OpenSSL 1.1.0j (Debian)      TLSv1.2 ECDHE-RSA-AES256-GCM-SHA384, 384 bit ECDH (P-384)
 OpenSSL 1.1.1b (Debian)      TLSv1.2 ECDHE-RSA-AES256-GCM-SHA384, 384 bit ECDH (P-384)
 Thunderbird (60.6)           TLSv1.2 ECDHE-RSA-AES256-GCM-SHA384, 384 bit ECDH (P-384)

 Done 2019-12-21 17:26:54 [  84s] -->> 163.172.157.89:443 (www.astar.org) <<--

Mais c’est un outsider et l’outil le plus courramment utilisé est probablement sslscan (disponible dans la plupart des repo linux). Il donne un peu moins de précision mais c’est pratique quand on veut juste l’essentiel :

$ sslscan www.astar.org
Version: 1.11.13-static
OpenSSL 1.0.2-chacha (1.0.2g-dev)

Connected to 163.172.157.89

Testing SSL server www.astar.org on port 443 using SNI name www.astar.org

  TLS Fallback SCSV:
Server does not support TLS Fallback SCSV

  TLS renegotiation:
Session renegotiation not supported

  TLS Compression:
Compression disabled

  Heartbleed:
TLS 1.2 not vulnerable to heartbleed
TLS 1.1 not vulnerable to heartbleed
TLS 1.0 not vulnerable to heartbleed

  Supported Server Cipher(s):
Preferred TLSv1.2  256 bits  ECDHE-RSA-AES256-GCM-SHA384   Curve P-384 DHE 384
Accepted  TLSv1.2  128 bits  ECDHE-RSA-AES128-GCM-SHA256   Curve P-384 DHE 384
Accepted  TLSv1.2  256 bits  DHE-RSA-AES256-GCM-SHA384     DHE 4096 bits
Accepted  TLSv1.2  128 bits  DHE-RSA-AES128-GCM-SHA256     DHE 4096 bits
Accepted  TLSv1.2  256 bits  ECDHE-RSA-AES256-SHA384       Curve P-384 DHE 384
Accepted  TLSv1.2  256 bits  ECDHE-RSA-AES256-SHA          Curve P-384 DHE 384
Accepted  TLSv1.2  256 bits  DHE-RSA-AES256-SHA256         DHE 4096 bits
Accepted  TLSv1.2  256 bits  DHE-RSA-AES256-SHA            DHE 4096 bits

  SSL Certificate:
Signature Algorithm: sha256WithRSAEncryption
RSA Key Strength:    2048

Subject:  www.astar.org
Altnames: DNS:bonny.astar.org, DNS:inglorious.astar.org, DNS:www.astar.org
Issuer:   Let's Encrypt Authority X3

Not valid before: Dec  3 02:55:59 2019 GMT
Not valid after:  Mar  2 02:55:59 2020 GMT

Ces deux outils vous offrent une sortie colorée (qu’on ne voit pas ici) dans le terminal pour rapidement pointer les problèmes.

Il est aussi utile de connaître le site badssl link qui permet de vérifier le niveau des vérifications SSL/TLS de votre navigateur (oui donc là ce n’est plus un test du serveur mais bien du client). C’est instructif également pour comprendre tout ce qu’on peut mal faire avec un certificat.

Petit bonus, l’outil ssh-audit (dispo aussi dans beaucoup de repo Linux) permet de vérifier la crypto de votre configuration SSH. La partie kex c’est pour l’algo d’échange de clé (asymétrique), key c’est les taille de clé, enc c’est pour l’algo de chiffrement (symétrique) et mac c’est pour le contrôle d’intégrité (ça veut dire message authentication code).
La aussi la ligne de commande est directe :

$ ssh-audit www.astar.org
# general
(gen) banner: SSH-2.0-OpenSSH_7.2p2 Ubuntu-4ubuntu2.8
(gen) software: OpenSSH 7.2p2
(gen) compatibility: OpenSSH 7.2+, Dropbear SSH 2013.62+
(gen) compression: enabled (zlib@openssh.com)

# key exchange algorithms
(kex) curve25519-sha256@libssh.org          -- [info] available since OpenSSH 6.5, Dropbear SSH 2013.62
(kex) ecdh-sha2-nistp256                    -- [fail] using weak elliptic curves
                                            `- [info] available since OpenSSH 5.7, Dropbear SSH 2013.62
(kex) ecdh-sha2-nistp384                    -- [fail] using weak elliptic curves
                                            `- [info] available since OpenSSH 5.7, Dropbear SSH 2013.62
(kex) ecdh-sha2-nistp521                    -- [fail] using weak elliptic curves
                                            `- [info] available since OpenSSH 5.7, Dropbear SSH 2013.62
(kex) diffie-hellman-group-exchange-sha256  -- [warn] using custom size modulus (possibly weak)
                                            `- [info] available since OpenSSH 4.4
(kex) diffie-hellman-group14-sha1           -- [warn] using weak hashing algorithm
                                            `- [info] available since OpenSSH 3.9, Dropbear SSH 0.53

# host-key algorithms
(key) ssh-rsa                               -- [info] available since OpenSSH 2.5.0, Dropbear SSH 0.28
(key) rsa-sha2-512                          -- [info] available since OpenSSH 7.2
(key) rsa-sha2-256                          -- [info] available since OpenSSH 7.2
(key) ecdsa-sha2-nistp256                   -- [fail] using weak elliptic curves
                                            `- [warn] using weak random number generator could reveal the key
                                            `- [info] available since OpenSSH 5.7, Dropbear SSH 2013.62
(key) ssh-ed25519                           -- [info] available since OpenSSH 6.5

# encryption algorithms (ciphers)
(enc) chacha20-poly1305@openssh.com         -- [info] available since OpenSSH 6.5
                                            `- [info] default cipher since OpenSSH 6.9.
(enc) aes128-ctr                            -- [info] available since OpenSSH 3.7, Dropbear SSH 0.52
(enc) aes192-ctr                            -- [info] available since OpenSSH 3.7
(enc) aes256-ctr                            -- [info] available since OpenSSH 3.7, Dropbear SSH 0.52
(enc) aes128-gcm@openssh.com                -- [info] available since OpenSSH 6.2
(enc) aes256-gcm@openssh.com                -- [info] available since OpenSSH 6.2

# message authentication code algorithms
(mac) umac-64-etm@openssh.com               -- [warn] using small 64-bit tag size
                                            `- [info] available since OpenSSH 6.2
(mac) umac-128-etm@openssh.com              -- [info] available since OpenSSH 6.2
(mac) hmac-sha2-256-etm@openssh.com         -- [info] available since OpenSSH 6.2
(mac) hmac-sha2-512-etm@openssh.com         -- [info] available since OpenSSH 6.2
(mac) hmac-sha1-etm@openssh.com             -- [warn] using weak hashing algorithm
                                            `- [info] available since OpenSSH 6.2
(mac) umac-64@openssh.com                   -- [warn] using encrypt-and-MAC mode
                                            `- [warn] using small 64-bit tag size
                                            `- [info] available since OpenSSH 4.7
(mac) umac-128@openssh.com                  -- [warn] using encrypt-and-MAC mode
                                            `- [info] available since OpenSSH 6.2
(mac) hmac-sha2-256                         -- [warn] using encrypt-and-MAC mode
                                            `- [info] available since OpenSSH 5.9, Dropbear SSH 2013.56
(mac) hmac-sha2-512                         -- [warn] using encrypt-and-MAC mode
                                            `- [info] available since OpenSSH 5.9, Dropbear SSH 2013.56
(mac) hmac-sha1                             -- [warn] using encrypt-and-MAC mode
                                            `- [warn] using weak hashing algorithm
                                            `- [info] available since OpenSSH 2.1.0, Dropbear SSH 0.28

# algorithm recommendations (for OpenSSH 7.2)
(rec) -diffie-hellman-group14-sha1          -- kex algorithm to remove 
(rec) -ecdh-sha2-nistp256                   -- kex algorithm to remove 
(rec) -ecdh-sha2-nistp384                   -- kex algorithm to remove 
(rec) -ecdh-sha2-nistp521                   -- kex algorithm to remove 
(rec) -ecdsa-sha2-nistp256                  -- key algorithm to remove 
(rec) -hmac-sha1                            -- mac algorithm to remove 
(rec) -hmac-sha2-256                        -- mac algorithm to remove 
(rec) -hmac-sha2-512                        -- mac algorithm to remove 
(rec) -umac-64@openssh.com                  -- mac algorithm to remove 
(rec) -umac-128@openssh.com                 -- mac algorithm to remove 
(rec) -hmac-sha1-etm@openssh.com            -- mac algorithm to remove 
(rec) -umac-64-etm@openssh.com              -- mac algorithm to remove 

Félicitation si vous avez tout ingurgité jusqu’ici. N’hésitez pas à m’écrire (dsoria+blog@astar.org) si vous constatez des oublis, des inexactitudes (non pas des erreurs) ou encore des améliorations.

David SORIA