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.

AcronymeFrançaisAnglais
CAAutorité de certificationCertificat Authority
KEYClé privéePrivate key
CSRDemande de signatureCertificat Signing Request
CRTCertificatCertificat


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.

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 🙂

Zephilou

Laisser un commentaire

Votre adresse de messagerie ne sera pas publiée. Les champs obligatoires sont indiqués avec *

Post comment