Certificat SSL/TLS Leaf avec openssl: passer aux courbes elliptiques sans changer d'autorité de certification

Rédigé par Frédéric Dumas Aucun commentaire
Classé dans : Administration système Mots clés : X.509, ssl, réseaux, hacking
Source: https://hackaday.com/2020/07/10/mmm-obfuscated-shell-donuts/
-----------------------------------------
On peut créer des certificats SSL/TLS basés sur les courbes elliptiques aussi facilement que ceux habituellement basés sur RSA.



En 2025 et 2026, il sera encore possible de faire signer par son autorité de certification commerciale habituelle, avec une validité d'un an, les certificats SSL/TLS "leaf" (ceux qu'on installe sur les serveurs HTTPS). Puis à partir d'avril 2026, cette période de validité des certificats SSL sera progressivement raccourcie, pour ne plus pouvoir excéder un mois, pour tous ceux signés après mars 2029. C'est la volonté de Google qui s'est imposée au sein de l'organisme de réglementation de ce type d'affaires, le Forum CA/Browser (en), dont les autorités de certifications comme les éditeurs de navigateurs web, respectent les décisions.

Autant dire que la génération manuelle des certificats SSL/TLS va peu à peu appartenir au passé, les administrateurs système étant contraints à automatiser leur renouvellement, plutôt que d'intervenir en personne tous les mois sur leurs serveurs. Cette situation est déjà connue à tous ceux qui font automatiquement signer leurs certificats par Let's Encrypt.

Générer manuellement une paire de clés à chiffrement asymétrique, puis soumettre la demande de signature de certificat correspondante à l'autorité de certification, restera une pratique en vigueur pendant quelques courtes années, jusqu'à ce que la fréquence de répétition de l'opération nous décourage tous.

Dans l'attente, ceux qui cherchent encore comment le faire trouveront de nombreux tutoriaux sur le web, expliquant l'usage de l'utilitaire en ligne de commande openssl. Une particularité de ces tutoriaux est qu'ils sont presque tous écrits pour générer des certificats utilisant des clés RSA de 2048 bits. Une valeur que le NIST déconseille de continuer à utiliser au-delà de 2030, compte tenu de l'increvable loi de Moore. Or, augmenter encore la taille des clés RSA alourdit proportionnellement celle des certificats leaf, qui sont portant transmis de manière frénétique par les serveurs, à chaque demande de négociation HTTPS provenant d'un navigateur web.

En comparaison, on ne sacrifie en rien la sécurité en choisissant les courbes elliptiques et une taille de clé de quelques centaines d'octets seulement, pour générer ce même couple de clés asymétriques et la demande de signature de certificat correspondante. Openssl supporte les courbes elliptiques depuis 15 ans tout aussi bien qu'il a supporté les clés RSA depuis aussi loin que la mémoire remonte. Passer aux algorithmes à courbes elliptiques présente l'avantage d'équiper ses serveurs de certificats SSL/TLS très légers en taille, tout en conservant au moins la même sécurité.

Il ne faut que connaitre les bonnes options à passer à openssl, et c'est ce que ce billet se propose d'explorer ici.


Générer la paire de clés



Traditionnellement, la composante privée de la clé RSA et la demande de signature de certificat (contenant la composante publique de la clé) se généraient toutes deux en une seule ligne de commande:
openssl req -new -newkey rsa:2048 -nodes -out request.csr -keyout private.key
Openssl permet pareillement de générer les composante privée et publique (à faire signer) de clés à courbe elliptique, mais cette fois-ci en deux commandes successives distinctes:
  • la première commande va générer la composante privée du couple et l'enregistrer dans le répertoire local sous le nom de fichier qu'on lui aura donné:
openssl ecparam -name prime256v1 -genkey -out ma_clef_elliptique_privee.key
  • la seconde commande va générer la demande de signature de la composante publique et l'enregistrer pareillement dans le répertoire local:
openssl req -new -key ma_clef_elliptique_privee.key -out ma_demande_de_certificat.csr
Cette seconde commande appelle donc en argument le fichier contenant la composante privée (ici ma_clef_elliptique_privee.key), créé par la première commande. Au final, le répertoire courant se trouvera peuplé de deux fichiers:
  • ma_clef_elliptique_privee.key - c'est la composante privée de la clé à courbe elliptique;
  • ma_demande_de_certificat.csr - c'est la composante publique, sous la forme d'une demande de signature à soumettre à l'autorité de certification.
On comprend que la longueur de la clé (ici 256 bits) dépend de l'option -name prime256v1 présente dans la première commande. En fait prime256v1 désigne davantage qu'un nombre de bits; en réalité ce nom désigne le jeu des paramètres (en) définissant la courbe elliptique choisie; ainsi, on ne peut passer à openssl qu'un jeu préexistant, parmi ceux qui lui sont connus.


La commande suivante permet d'afficher la liste des jeux de paramètres disponibles:
openssl ecparam -list_curves
Cette liste parait impressionnante de longueur, mais pour l'usage d'un certificat SSL/TLS qui recherche la plus large compatibilité, le choix se limite à un seul jeu de paramètres recommandé:  prime256v1.

La demande de signature de certificat .csr est alors à soumettre à l'autorité de certification choisie; selon le type de certificat commandé auprès d'elle (portant sur le seul domaine - certificat "dv", ou sur l'identité légale du site web - certificats "ov"), le type d'information à inclure dans la demande de signature .csr peut varier. Voici les questions que pose openssl au moment où il va générer le .csr:

You are about to be asked to enter information that will be incorporated
into your certificate request.
What you are about to enter is what is called a Distinguished Name or a DN.
There are quite a few fields but you can leave some blank
For some fields there will be a default value,
If you enter '.', the field will be left blank.
-----
Country Name (2 letter code) [AU]:
State or Province Name (full name) [Some-State]:
Locality Name (eg, city) []:
Organization Name (eg, company) [Internet Widgits Pty Ltd]:
Organizational Unit Name (eg, section) []:
Common Name (e.g. server FQDN or YOUR name) []:
Email Address []:

Please enter the following 'extra' attributes
to be sent with your certificate request
A challenge password []:
An optional company name []:

Le plus souvent, parmi ces questions posées à la création du .csr, seul le champ Common Name a besoin d'être renseigné (il a été mis en gras dans l'exemple ci-dessus), et doit contenir le domaine pour lequel le certificat SSL/TLS émis sera signé. Les autres champs, quelques soient les informations renseignées manuellement, sont alors purement et simplement ignorés par l'autorité de certification: elle ne les inclut tout simplement pas dans le certificat leaf. À noter enfin qu'on ne donne en pratique jamais de mot de passe à cette étape, car la demande de signature de certificat ne contient de toute façon que la composante publique de la clé, et en limiter l'accès par mot de passe poserait le problème supplémentaire de sa transmission en parallèle à l'autorité de certification. La pratique consiste donc à n'en définir aucun.


Vérifier le contenu des certificats manipulés



On pourra ensuite vouloir utiliser encore openssl pour:
  • satisfaire sa curiosité, et afficher le contenu de la demande de signature de certificat qu'on a générée l'instant d'avant;
  • afficher le contenu du certificat leaf signé par, et reçu en retour de l'autorité de certification;
  • vérifier qu'il forme bien la paire avec la composante privée qu'on a conservé par devers soi.

Afficher le contenu du CSR



La commande suivante est à utiliser pour afficher en texte clair le contenu de la demande de signature de certificat:

openssl req -text -noout -verify -in ma_demande_de_certificat.csr


Certificate request self-signature verify OK
Certificate Request:
    Data:
        Version: 1 (0x0)
        Subject: C=FR, ST=Some-State, O=Internet Widgits Pty Ltd, CN=mon_nom.de_domaine.fr
        Subject Public Key Info:
            Public Key Algorithm: id-ecPublicKey
                Public-Key: (256 bit)
                pub:
                    04:c8:2b:81:cd:f6:94:d4:b0:79:f0:f9:b7:0b:85:
                    [SNIP]
                    e6:d3:bb:96:b1
                ASN1 OID: prime256v1
                NIST CURVE: P-256
        Attributes:
            (none)
            Requested Extensions:
    Signature Algorithm: ecdsa-with-SHA256
    Signature Value:
        30:44:02:20:10:96:5c:b8:6d:c7:3b:01:a8:fe:92:9a:a1:50:
        [SNIP]
        1a:8e:cc:7d:2d:87:17:df:46:52:db:18:84:12:66:3d

À noter que l'intrigante mention de la société "Internet Widgits Pty Ltd" apparaissant dans le champ "Organisation" ne doit pas inquiéter; elle est automatiquement ajoutée par openssl lorsque précisément aucun nom de société n'a été renseigné par l'utilisateur. Elle est simplement ignorée par l'autorité de certification.


Afficher le contenu du certificat leaf



La commande suivante est à utiliser pour afficher en texte clair le contenu du certificat leaf finalement reçu signé de l'autorité de certification:

openssl x509 -text -noout -in mon_certificat_signe.pem

La présence de l'option -noout sert simplement à éviter la répétition du certificat .pem encodé en base64 à la suite du texte en clair.


Vérifier la concordance des composantes privée et publique



Les commandes suivantes permettront de comparer:

  • la composante publique de la clé, reconstruite à partir de la composante privée:
openssl pkey -pubout -in ma_clef_elliptique_privee.key

-----BEGIN PUBLIC KEY-----
MIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEA7h+LQ4Ro+CWNzrCFCuel
[SNIP]
wgc8RbylSI4SgqyqGXc76ysCAwEAAQ==
-----END PUBLIC KEY-----

avec:

  • la composante publique de la clé, telle quelle apparait dans le certificat signé par l'autorité de certification:
openssl x509 -noout -pubkey -in mon_certificat_signe.pem

 -----BEGIN PUBLIC KEY-----
MIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEA7h+LQ4Ro+CWNzrCFCuel
[SNIP]
wgc8RbylSI4SgqyqGXc76ysCAwEAAQ==
-----END PUBLIC KEY-----


La lecture visuelle des deux résultats permet de confirmer que la composante publique présente dans le certificat leaf qui vient d'être signé, est effectivement identique à celle re-générée à partir de la composante privée, conservée localement.


Chainer les certificats



Maintenant que le certificat SSL/TLS et sa clé privée correspondante sont prêts à être installés sur le serveur web, reste pourtant une étape un peu ingrate à franchir: à la suite du certificat leaf signé par l'autorité de certification, il faut encore concaténer dans le même fichier le certificat intermédiaire depuis lequel l'autorité de certification a signé le certificat leaf.

Root Certificate (Trusted by the browser)
└── Intermediate Certificate 1 (Signed by Root Certificate)
    └── Intermediate Certificate 2 (Signed by Intermediate Certificate 1)
        └── End-Entity Certificate (Your Website's Certificate, signed by Intermediate Certificate 2)

Source: https://github.com/nicanorflavier/ssl-certificate-chain-guide

Un simple copier-coller, pas bien compliqué en somme, mais qui nécessite un peu de travail (il existe des sites web qui le font pour vous):
  • identifier le certificat intermédiaire utilisé par l'autorité de certification;
  • le télécharger en format .pem;
  • copier-coller son contenu dans le fichier du certificat leaf, en-dessous du corps du certificat leaf;
  • éventuellement répéter cette opération si l'autorité de certification a utilisé un second certificat intermédiaire, supérieur en hiérarchie au premier, mais inférieur à son certificat root;
  • s'interdire d'ajouter encore le certificat root de l'autorité de certification, qui par définition est déjà connu des navigateurs web et des systèmes d'exploitation.
La valeur cryptographique du certificat leaf seul est la même que lorsqu'il est chainé dans le même fichier au certificat intermédiaire depuis lequel il a été signé; cependant, permettre ainsi au serveur web de fournir d'emblée aux navigateurs web la totalité de la chaine de certification (à l'exception du certificat root, connu de tous), accélère la négociation de la session SSL/TLS.






Creative Commons Attribution-ShareAlike 4.0 International
Pour joindre l'auteur: f.dumas@ellis.siteparc.fr



Écrire un commentaire

Quelle est le deuxième caractère du mot t0nb7c ?