Créer une autorité de certification (CA) avec OpenSSL
Aujourd’hui on va créer une autorité de certification (CA) OpenSSL.
Pour augmenter la sécurité de votre infrastructure vous pouvez créer vous même une autorité de certification et générer vos propres certificats.
Cet article fait suite à la création de certificat auto-signé mais sans autorité de certification : https://sysadmin.cyklodev.com/creer-un-certificat-ssl-auto-signe-pour-nginx/
On va utiliser le vénérable OpenSSL pour créer l’autorité et les certificats. Pour vous fixer les idées on commence par une série d’acronymes.
Acronyme | Français | Anglais |
CA | Autorité de certification | Certificat Authority |
KEY | Clé privée | Private key |
CSR | Demande de signature | Certificat Signing Request |
CRT | Certificat | Certificat |
[cyklodev_summary]
Création du CA
Configuration des variables
On va créer un répertoire pour faire notre petite cuisine.
mkdir openssl && cd openssl
Clé du CA
On commence par le plus important, la clé privé de votre autorité de certification. Elle sera à préserver de tout, alors prenez en soin et protégez la (vol, perte, suppression, etc ).
C’est elle qui vous permettra de signer de nouveaux certificats.
[zeph@server openssl]$ openssl genrsa -out CA-ROOT.key
Generating RSA private key, 2048 bit long modulus
...................................................................+++
.................+++
e is 65537 (0x10001)
Faire sa demande de signature
Un fois la clé privée générée, on fait la demande de signature à partir de cette clé privée.
Plusieurs paramètres sont à fournir. Pensez bien à ces paramètres, car nous les réutiliserons plus tard, et ils feront partis de la signature des tous les certificats que vous émettrez.
[zeph@server openssl]$ openssl req -new -key CA-ROOT.key -out CA-ROOT.csr -sha256
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) [XX]:FR
State or Province Name (full name) []:France
Locality Name (eg, city) [Default City]:Strasbourg
Organization Name (eg, company) [Default Company Ltd]:Cyklodev
Organizational Unit Name (eg, section) []:Auth
Common Name (eg, your name or your server's hostname) []:CA-ROOT
Email Address []:support@cyklodev.com
Please enter the following 'extra' attributes
to be sent with your certificate request
A challenge password []:CHANGETHIS
An optional company name []:
Signature du certificat
Et enfin on génère le certificat d’autorité du CA à partir de la clé privée. Comprenez bien qu’a cette étape on s’autosigne car rien n’est au dessus de nous.
[zeph@server openssl]$ openssl x509 -req -days 365 -in CA-ROOT.csr -out CA-ROOT.crt -signkey CA-ROOT.key
Signature ok
subject=/C=FR/ST=France/L=Strasbourg/O=Cyklodev/OU=Auth/CN=CA-ROOT/emailAddress=support@cyklodev.com
Getting Private key
On se retrouve maintenant avec les 3 fichiers suivants:
[zeph@server openssl]$ ll
-rw-rw-r--. 1 zeph zeph 1306 Nov 4 18:40 CA-ROOT.crt
-rw-rw-r--. 1 zeph zeph 1123 Nov 4 18:40 CA-ROOT.csr
-rw-rw-r--. 1 zeph zeph 1675 Nov 4 18:37 CA-ROOT.key
On peut supprimer le CA-ROOT.csr qui ne nous sert plus et on protège la clé contre une éventuelle suppression.
[zeph@server openssl]$ rm -fv CA-ROOT.csr
[zeph@server openssl]$ chmod 400 CA-ROOT.key
Création de la configuration du CA
Pour la suite des opérations, il va falloir créer un fichier de configuration correspondant à notre autorité de certification. C’est ce fichier de configuration qui va établir et créer une autorité de certification (CA) OpenSSL.
Le fichier
On va rester basique en ne mettant que le minimum fonctionnel.
[zeph@server openssl]$ vi ca-ssl.conf
[ ca ]
default_ca = cyklodev_ca
[ cyklodev_ca ]
# ROOT CA
certificate = CA-ROOT.crt
private_key = CA-ROOT.key
new_certs_dir = .
database = ./index.txt
serial = ./serial
default_md = sha512
default_days = 365
policy = cyklodev_policy
[ cyklodev_policy ]
countryName = match
stateOrProvinceName = match
organizationName = match
organizationalUnitName = optional
commonName = supplied
emailAddress = optional
[ req ]
default_bits = 2048
distinguished_name = req_distinguished_name
string_mask = utf8only
default_md = sha512
Les pré requis
Avec ce fichier de configuration minimum il va nous falloir 2 choses:
- un fichier serial qui incrémentera avec le nombre de certificats que l’on va signer
- un fichier index.txt qui va garder la trace de chaque certificat émis
[zeph@server openssl]$ touch index.txt
[zeph@server openssl]$ echo '01' > serial
Avec tout ça, on va pouvoir maintenant générer notre 1er certificat ou plutôt voir le processus global de signature.
Processus de signature
La création d’un certificat suit toujours le même parcours:
- Création de la clé (KEY)
- Création de la demande de signature (CSR)
- Signature du certificat (CRT)
Pour être plus précis cela peut se dérouler de 2 façons, selon comment vous voulez gérer. On peut se representer le processus selon le schema suivant.
Le CA autoritaire
La version la plus simple, c’est vous qui gérer les 3 phases. Vous créez donc la clé, vous choisissez le nom du certificat et bien sur c’est vous qui signez.
Le CA signataire
Ce cas ci est plus proche de la réalité des autorités de certifications établies.
Votre client génère sa clé chez lui ainsi que son fichier csr pour la demande de certification. Ensuite il ne vous transmet que ce fichier csr.
De votre coté vous avez la charge de vérifier si sa demande est bonne, puis de la signer et enfin de transmettre le certificat au demandeur.
Signer son premier certificat
Dans ce 1er cas, on va prendre comme exemple un certificat pour le site
customCA-cert1.fqdn.dom
Création de la clé privé
On commence par créer la clé pour une meilleure lisibilité je vais nommé tous les fichiers par le nom de domaine du certificat que je souhaite signer.
[zeph@server openssl]$ openssl genrsa -out customCA-cert1.fqdn.dom.key
Generating RSA private key, 2048 bit long modulus (2 primes)
.........................................+++++
...................................+++++
e is 65537 (0x010001)
Générer la demande de signature
Maintenant, il faut générer le fichier csr en remplissant correctement les champs.
[zeph@server openssl]$ openssl req -new -key customCA-cert1.fqdn.dom.key -out customCA-cert1.fqdn.dom.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]:FR
State or Province Name (full name) [Some-State]:France
Locality Name (eg, city) []:Strasbourg
Organization Name (eg, company) [Internet Widgits Pty Ltd]:Cyklodev
Organizational Unit Name (eg, section) []:Auth
Common Name (e.g. server FQDN or YOUR name) []:customCA-cert1.fqdn.dom
Email Address []:support@cyklodev.com
Please enter the following 'extra' attributes
to be sent with your certificate request
A challenge password []:
An optional company name []:
Il est possible de mettre un mot de passe au csr, il convient alors de transmettre le mot de passe au certificateur en plus du fichier csr.
Vérifier la demande de signature
On se place dans le cas du processus signataire, on va maintenant vérifier la demande.
[zeph@server openssl]$ openssl req -text -noout -verify -in customCA-cert1.fqdn.dom.csr | grep Subject:
verify OK
Subject: C = FR, ST = France, L = Strasbourg, O = Cyklodev, OU = Auth, CN = customCA-cert1.fqdn.dom, emailAddress = support@cyklodev.com
Il convient de vérifier si le demandeur est légitime et si le sujet du certificat est correct.
Signer le certificat
En possession du fichier csr, il reste à le mettre dans le répertoire où se situe la paire clé/certificat CA-ROOT ainsi que le fichier de configuration.
[zeph@server openssl]$ openssl ca -config ca-ssl.conf -out customCA-cert1.fqdn.dom.crt -in customCA-cert1.fqdn.dom.csr
Using configuration from ca-ssl.conf
Check that the request matches the signature
Signature ok
The Subject's Distinguished Name is as follows
countryName :PRINTABLE:'FR'
stateOrProvinceName :ASN.1 12:'France'
localityName :ASN.1 12:'Strasbourg'
organizationName :ASN.1 12:'Cyklodev'
organizationalUnitName:ASN.1 12:'Auth'
commonName :ASN.1 12:'customCA-cert1.fqdn.dom'
emailAddress :IA5STRING:'support@cyklodev.com'
Certificate is to be certified until Nov 17 07:02:29 2021 GMT (365 days)
Sign the certificate? [y/n]:y
1 out of 1 certificate requests certified, commit? [y/n]y
Write out database with 1 new entries
Data Base Updated
On voit le récapitulatif du CSR, et on a la possibilité de le signer vu qu’il respecte les règles définies dans le fichier de configuration.
On peut aussi remarque que la durée de validité du certificat est de 365, également en provenance du fichier de configuration (default_days).
Transmettre le certificat
Il est temps de transmettre le certificat au demandeur, comme ce certificat dépend de sa clé privée vous pouvez l’envoyer sans utiliser un canal sécurisé.
Par contre si c’est vous (l’autorité) qui avez généré la clé privée, alors il faut utiliser un canal sécurisé (scp,archive avec mot de passe,etc…).
Comme notre certificat provient d’un CA qui n’est pas reconnu, il faudra également transmettre le CA-ROOT.crt pour que l’autorité soit reconnu moyennant un import en tant que certification approuvée par l’entreprise.
Générer un certificat non conforme
Plus d’explication sur la configuration
On a vu plus haut que le fichier de configuration utilisé est un minimum fonctionnel. Dedans il y a la section policy qui nous intéresse:
[ cyklodev_policy ]
countryName = match
stateOrProvinceName = match
organizationName = match
organizationalUnitName = optional
commonName = supplied
emailAddress = optional
On y voit 3 contraintes possibles:
- match: ce champ devra être identique entre le CSR et la configuration du CA
- optional: on peut laisser ce champ vide lors de la génération du CSR
- supplied: ce champs doit obligatoirement défini lors de la générationdu CSR
Un exemple non conforme
On va prendre comme exemple un certificat qui ne respecte pas la contrainte sur le champ organizationName.
On suit le même cheminement : clé, csr, puis signature
[zeph@server openssl]$ openssl genrsa -out customCA-cert2.fqdn.dom.key
Generating RSA private key, 2048 bit long modulus (2 primes)
.........+++++
.....................+++++
e is 65537 (0x010001)
[zeph@server openssl]$ openssl req -new -key customCA-cert2.fqdn.dom.key -out customCA-cert2.fqdn.dom.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]:FR
State or Province Name (full name) [Some-State]:France
Locality Name (eg, city) []:Strasbourg
Organization Name (eg, company) [Internet Widgits Pty Ltd]:HallyBourton
Organizational Unit Name (eg, section) []:Auth
Common Name (e.g. server FQDN or YOUR name) []:customCA-cert2.fqdn.dom
Email Address []:support@cyklodev.com
Please enter the following 'extra' attributes
to be sent with your certificate request
A challenge password []:
An optional company name []:
Ici on arrive au moment de signer le CSR.
[zeph@server openssl]$ openssl ca -config ca-ssl.conf -out customCA-cert2.fqdn.dom.crt -in customCA-cert2.fqdn.dom.csr
Using configuration from ca-ssl.conf
Check that the request matches the signature
Signature ok
The Subject's Distinguished Name is as follows
countryName :PRINTABLE:'FR'
stateOrProvinceName :ASN.1 12:'France'
localityName :ASN.1 12:'Strasbourg'
organizationName :ASN.1 12:'HallyBourton'
organizationalUnitName:ASN.1 12:'Auth'
commonName :ASN.1 12:'customCA-cert2.fqdn.dom'
emailAddress :IA5STRING:'support@cyklodev.com'
The organizationName field is different between
CA certificate (Cyklodev) and the request (HallyBourton)
Comme prévu par le fichier de configuration, il est impossible d’emettre un certificat pour cette demande car l’organizationName de correspond pas.
Epilogue
Vous avez tout en main pour créer une autorité de certification (CA) OpenSSL maison. Le seul point necessaire, sera d’ajouter votre certificat CA-ROOT en autorité de confiance.
=== INSERER UN FUTUR ARCTICLE ICI ===
En effet la liste des certificats reconnus officiellement est maintenu par tous les composants gérant des certificats.
- Android: https://android.googlesource.com/platform/system/ca-certificates/+/master/files/
- Apple : https://support.apple.com/fr-fr/HT209144#trusted
- Firefox : https://ccadb-public.secure.force.com/mozilla/CAInformationReport
- Microsoft : https://ccadb-public.secure.force.com/microsoft/IncludedCACertificateReportForMSFT
Gardez en memoire que cette configuration est la plus basique qui soit. Vous pouvez consulter le fichier complet sur votre systeme.
RHEL/Centos : /etc/pki/tls/openssl.cnf
A vous de jouer signer 🙂