Gestion de certificats x509
Que sont les certificats x509 ?
D'après Wikipedia, x509 est une norme définissant le format des certificats de type clé publique. Ils sont utilisés dans de nombreux protocoles Internet, dont TLS/SSL, qui est à la base de HTTPS (le protocole de navigation sécurisé sur le Web).
But
Le but d'avoir ma propre autorité de certification (CA) me permet de générer des certificats auto-signés pour des utilisations non publiques. Mes services étant hébergés sur mon propre réseau privé m'empêchent d'obtenir des certificats gratuits de la populaire autorité certification Let's Encrypt.
Vu que j'héberge plus d'un service et que je veux que tous mes appareils (ordinateur portable, téléphone, ...) puissent y avoir accès sans avoir à installer de certificat toutes les 3 semaines (lorsque je mets à jour les noms d'hôtes par exemple). J'ai décidé de créer ma propre autorité de certification et de générer des certificats signés et validés par celle-là. De cette façon, je n'ai qu'à installer l'autorité de certification racine sur tous mes appareils pour que cela fonctionne.
Création de ma propre autorité de certification
Tout ce dont j'ai besoin est un environnement Linux et openssl
.
Génération du secret
Tout d'abord je génère la clé privée avec la commande suivante :
Résultat :
Generating RSA private key, 4096 bit long modulus
.................................................................++
......................................................................................................................................................................++
e is 65537 (0x10001)
J'ai maintenant une belle clé privée :
-----BEGIN RSA PRIVATE KEY-----
MIIJKAIBAAKCAgEA2IxiR6U/B6Ypd1/3KG5Pxk/BY47HzHpBAHnEFsMHdcpCNNXO
GxqhUsIHBGMc0I2xa0WiyNJB4k5qGwL58J1TK/kKaW8yOOGajawvhjL/6bYXgN1I
[...]
rcL3YJyl/m0mlYl80syPPViHM9TD7uwQi/M9DPeOGLwVuCYzpl3qAkQRaTwQc2Ev
5hffBNz+evhf2Q7iUCmWQFizIFlFpOCq1f/jvpleqf8ChG6EhNRgvAFIUMc=
-----END RSA PRIVATE KEY-----
Ce fichier doit être gardé secret et stocké de manière sécurisé hors ligne.
Génération de la configuration du certificat
Maintenant que j'ai la partie secrète, je dois générer la partie publique : le certificat x509. En utilisant de la configuration OpenSSL par défaut :
[ req ]
default_bits = 4096
default_keyfile = root-CA.key
encrypt_key = no
utf8 = yes
distinguished_name = req_distinguished_name
prompt = no
x509_extensions = v3_ca
[ req_distinguished_name ]
countryName = FR
stateOrProvinceName = France
localityName = Paris
organizationName = Example
commonName = example.org
[ v3_ca ]
subjectKeyIdentifier = hash
basicConstraints = critical,CA:true,pathlen:1
keyUsage = critical,keyCertSign
Cette configuration doit être conservée pour la prochaine fois que je dois regénérer le certificat racine. Gardez à l'esprit que ce certificat ne doit pas être modifié trop souvent, sinon cela rendrait l'objectif principal inutile.
Vous pouvez ajuster cette configuration en fonction de vos besoins.
Génération du certificat racine
En utilisant la configuration précédente, j'ai généré l'autorité de certification racine auto-signée :
openssl req -x509 -new -nodes \
-config root-CA-openssl.cnf \
-key root-CA.key \
-sha256 -days 1024 \
-out root-CA.crt
Vérification du contenu du certificat :
Résultat :
Certificate:
Data:
Version: 1 (0x0)
Serial Number: 11676879669831540892 (0xa20c9c31654a209c)
Signature Algorithm: sha256WithRSAEncryption
Issuer: C=FR, ST=France, L=Paris, O=Example, CN=example.org
Validity
Not Before: Feb 6 15:53:58 2022 GMT
Not After : Nov 26 15:53:58 2024 GMT
Subject: C=FR, ST=France, L=Paris, O=Example, CN=example.org
[...]
X509v3 extensions:
X509v3 Subject Key Identifier:
F1:FA:C4:50:A4:7F:53:D3:6C:D5:EF:48:72:24:B8:CE:08:10:3F:94
X509v3 Basic Constraints: critical
CA:TRUE, pathlen:1
X509v3 Key Usage: critical
Certificate Sign
[...]
Cette commande génère le fichier certificat et signe son contenu avec la clé privée.
J'ai maintenant un certificat d'autorité, je peux générer tous les certificats de mes applications et les signer avec.
Créer des certificats pour mes applications
Génération du secret
Comme pour l'autorité de certification racine, j'ai besoin de générer une clé secrète.
Je peux utiliser une commande identique à précédemment :
Génération de la configuration openssl
Je dois maintenant créer la configuration OpenSSL pour mon certificat en utilisant la configuration OpenSSL par défaut :
[ req ]
default_bits = 2048
default_keyfile = my-app.key
encrypt_key = no
utf8 = yes
distinguished_name = req_distinguished_name
req_extensions = v3_req
prompt = no
[ req_distinguished_name ]
countryName = FR
stateOrProvinceName = France
localityName = Paris
organizationName = Example
commonName = my-app.example.org
[v3_req]
subjectKeyIdentifier = hash
subjectAltName = @alt_names
[ alt_names ]
DNS.1 = my-app.example.org
DNS.2 = extra.my-app.example.org
Notez ici que le paramètre subjectAltName
et les alt_names
sont très importants. Désormais, chaque navigateur ou application sur téléphone nécessite que le nom d'hôte exposé par l'application Web soit spécifié dans cette section.
Vous pouvez toujours ajouter plusieurs noms alternatifs au certificat. Cela vous permet d'utiliser le même certificat pour plusieurs applications. Assurez-vous d'utiliser un certificat différent en fonction du niveau de sécurité dont vous avez besoin pour vos applications.
Génération de la demande de certificat
Afin de générer un certificat signé par mon autorité de certification racine, je dois générer une demande de certificat. À l'aide de la commande suivante, je peux générer la requête et la signer avec la clé privée de l'application :
Je peux vérifier le contenu de ma demande avec :
Résultat :
Certificate Request:
Data:
Version: 0 (0x0)
Subject: C=FR, ST=France, L=Paris, O=Example, CN=my-app.example.org
[...]
Signer mon certificat d'application avec l'autorité de certification racine
Enfin, je dois utiliser mon autorité de certification racine pour générer mon certificat d'application en fonction de la demande et garantir son authenticité.
J'ai seulement besoin d'utiliser la commande suivante :
openssl x509 -req \
-CA root-CA.crt \
-CAkey root-CA.key \
-CAcreateserial \
-in my-app.csr \
-days 500 -sha256 \
-out my-app.crt
Pour vérifier le contenu du certificat nouvellement généré, je peux exécuter la commande suivante :
Résultat :
Certificate:
Data:
Version: 1 (0x0)
Serial Number: 15807445207358136962 (0xdb5f53aa27086282)
Signature Algorithm: sha256WithRSAEncryption
Issuer: C=FR, ST=France, L=Paris, O=Example, CN=example.org
Validity
Not Before: Feb 6 16:22:38 2022 GMT
Not After : Jun 21 16:22:38 2023 GMT
Subject: C=FR, ST=France, L=Paris, O=Example, CN=my-app.example.org
Vérification de la chaîne de confiance complète
Maintenant que j'ai le certificat de mon application, je dois m'assurer que l'autorité de certification racine en valide l'authenticité.
En utilisant une dernière commande openssl
:
Résultat :