Mes documentations

« Retour à l'accueil

Création d'une autorité de certification locale avec OpenSSL

Date de rédaction: octobre 2007

Cette page décrit un exemple de processus de création d’une autorité de certification, son organisation, ainsi que la génération et la signature d’un certificat serveur.

Intérêt d’une autorité locale

Une autorité de certification (AC) locale repose sur un certificat SSL racine auto-signé qui certifira l’authenticité des certificats serveurs ou personnels qu’il signera.

Les certificats ainsi signés ne seront bien entendu par défaut pas reconnus par les logiciels clients, qui alerteront donc généralement l’utilisateur de l’utilisation d’un certificat non reconnu.

L’utilisation d’une AC locale peut cependant être intéressante si on souhaite déployer le certificat racine au sein d’une organisation (en l’intégrant aux magasins de certificats des logiciels interrogeant les services qui utilisent les certificats serveurs), ce qui permet ensuite de déployer et renouveler les certificats serveur sans effet sur les utilisateurs.

Création d’une nouvelle autorité

Création des fichiers et répertoires

L’autorité de certification nécessite plusieurs fichiers de configuration indiquant les répertoires de destination des certificats générés, ainsi que divers fichiers indiquant par exemple le numéro de série du dernier certificat signé, etc.

On peut placer tous ces fichiers dans un répertoire prévu par votre distributions (comme /etc/ssl sous Debian), mais je préfère utiliser ma propre organisation dans un autre répertoire.

N’oubliez pas que de la sécurité de la machine sur laquelle vous installez l’AC dépend celle de la clef privée permettant la signature du certificat, et donc de la sécurité des certificats serveurs que vous signerez.

Dans un répertoire de son choix, on va donc créer les répertoires et les premiers fichiers nécessaires :

mkdir -p Autorite/certs
mkdir -m 700 -p Autorite/AC/{private,newcerts,crl}
chmod 700 Autorite/AC/private
touch Autorite/AC/index.txt
echo 01 > AC/serial
cp /etc/ssl/openssl.cnf Autorite/

On édite ensuite le fichier de configuration pour le modifier selon nos besoins (voir ci-dessous).

Adapter openssl.conf à vos besoins

En se basant sur le fichier openssl.conf par défaut fourni par votre système (présent dans /etc/ssl sous Debian), on va créer un nouveau fichier qu’on placera dans le répertoire AC.

Dans ce fichier :

Voici un extrait de ce fichier openssl.conf :

[ ca ]
default_ca      = AC_locale

[ AC_locale ]

dir             = ./AC                  # Where everything is kept
certs           = $dir/certs            # Where the issued certs are kept
crl_dir         = $dir/crl              # Where the issued crl are kept
database        = $dir/index.txt        # database index file.
#unique_subject = no                    # Set to 'no' to allow creation of
                                        # several certificates with same subject.
new_certs_dir   = $dir/newcerts         # default place for new certs.

certificate     = $dir/ca-local.crt     # The CA certificate
serial          = $dir/serial           # The current serial number
crlnumber       = $dir/crlnumber        # the current crl number. must be
                                        # commented out to leave a V1 CRL
crl             = $dir/ca-lille3.crl    # The current CRL
private_key     = $dir/private/ca.key   # The private key
#RANDFILE       = $dir/private/.rand    # private random number file
RANDFILE        = /dev/random           # private random number file

x509_extensions = usr_cert              # The extentions to add to the cert

name_opt        = ca_default            # Subject Name options
cert_opt        = ca_default            # Certificate field options

# Extensions to add to a CRL. Note: Netscape communicator chokes on V2 CRLs
# so this is commented out by default to leave a V1 CRL.
# crlnumber must also be commented out to leave a V1 CRL.
crl_extensions  = crl_ext

default_days    = 1095                  # how long to certify for
default_crl_days= 30                    # how long before next CRL
default_md      = sha1                  # which md to use.
preserve        = no                    # keep passed DN ordering

# On utilise la politique policy_match définie ci-dessous, qui oblige à faire
# correspondre countryName, stateOrProvinceName et organizationName, nécessite
# un commonName et supporte en option organizationalUnitName et emailAddress
policy          = policy_match

# For the CA policy
[ policy_match ]
countryName             = match
#stateOrProvinceName    = match
stateOrProvinceName     = optional
organizationName        = match
# utiliser ça si on veut être moins strict :
#countryName            = optional
#stateOrProvinceName    = optional
#organizationName       = optional
organizationalUnitName  = optional
commonName              = supplied
emailAddress            = optional

[ req ]
default_bits            = 1024
#default_keyfile        = privkey.pem
default_keyfile         = new.key
distinguished_name      = req_distinguished_name
#attributes             = req_attributes
x509_extensions = v3_ca # The extentions to add to the self signed cert
string_mask = nombstr
req_extensions = v3_req # The extensions to add to a certificate request

[ req_distinguished_name ]
countryName                     = Nom du pays (code à deux lettres)
countryName_default             = FR
countryName_min                 = 2
countryName_max                 = 2

stateOrProvinceName             = Etat, region, ou province (nom complet)
stateOrProvinceName_default     = Nord-Pas-de-Calais

localityName                    = Nom de la localite (p.e. la ville)
localityName_default            = "Villeneuve d'Ascq"

0.organizationName              = Nom de l'organisation (p.e. l'entreprise)
0.organizationName_default      = Acme, Inc.

organizationalUnitName          = Département de l'organisation (p.e. le service)
organizationalUnitName_default  = Usine de docs

commonName                      = Common Name (p.e. le nom du serveur)
commonName_max                  = 64

emailAddress                    = Adresse electronique
emailAddress_max                = 64

Par défaut sous Debian, openssl utilise le fichier /etc/ssl/openssl.conf qui désigne le répertoire /etc/ssl/certs pour le stockage des certificats racine. Sur les postes clients, on peut donc y placer les certificats les plus connus, pour que, après l’utilisation de c_rehash dans ce répertoire, les applications utilisant openssl (comme un serveur mail, etc.) trouveront toutes seules ces certificats.

Génération de la clef privée

On génère ensuite une clef rsa privée pour l’autorité, en lui donnant une phrase de passe (un long mot de passe compliqué que vous garderez bien secret). Cette clef est essentielle pour la sécurité de l’AC, il faut dont veiller à en protéger l’accès (notamment des utilisateurs non privilégiés du système, par exemple), et ne pas la perdre.

openssl genrsa -out Autorite/private/cakey.pem 1024

On génère le certificat autosigné qui sera à la base de l’autorité de certification. Openssl demandera de saisir les informations à utiliser. Le CN (Common Name) demandé sera affiché par les applications comme nom de l’autorité de certification (exemple : Autorite Certifiante d’Acme).

openssl req -new -x509 -key Autorite/private/cakey.pem \
	-out Autorite/certs/cacert.pem -days 1460

Notre autorité de certification est maitenant prête, on peut commencer à créer et signer un certificat serveur.

Création d’une requête de certificat

À moins d’utiliser la configuration par défaut /etc/ssl/openssl.cnf, il faut désigner dans le variable d’environnement OPENSSL_CONF le fichier de configuration que la commande openssl devra utiliser (pour retrouver le certificat d’autorité et la clef à utiliser, ainsi que des valeurs par défaut, etc.)

export OPENSSL_CONF=/root/AutoriteDeCertification/openssl.cnf

On commence par créer de la clef privée pour la requête, non chiffrée pour éviter d’avoir un mot de passe à saisir lors du démarrage du service (apache par exemple). Attention: empêcher la lecture de cette clef par un autre que root !, même (voire surtout) une fois installée sur le serveur de destination.

La création automatique de cette clef est possible lors de la génération de la requête, mais la clef serait alors automatiquement chiffrée, il faudrait la déchiffrer ensuite. On la crée donc manuellement :

openssl genrsa -out web1-dev-key.pem 1024

On crée ensuite la requête de certificat. Si on a bien paramétré le fichier openssl.cnf, on peut utiliser les informations par défaut pour renseigner les champs demandés par openssl. Il suffira de préciser le nom du serveur pour le CN : utilisez le nom dns pleinement qualifié, par exemple www.domaine.dpn :

openssl req -new -key web1-dev-key.pem -out web1-dev-req.pem

Signature par l’authorité de certification

La signature de la requête par l’authorité de certification se fait en une seule commande :

openssl ca -out web1-cert.pem -in web1-dev-req.pem

Le certificat signé apparait alors dans AC/newcerts/$(cat AC/serial).pem en plus du fichier désigné par l’option -out de la commande.

Il suffit ensuite d’installer la clef privée du certificat et le certificat signé par l’autorité sur le serveur de destination. Pour ceci, consulter la documentation du serveur qui doit utiliser cette clef (votre serveur web, mail, etc.).

Commandes utiles

Voici quelques commandes openssl utiles pour lire ou manipuler les certifcats ou les clefs SSL :

openssl x509 -in moncert.pem -text
openssl rsa -in mykey.pem -text
(openssl x509 -noout -modulus -in server.pem | openssl md5 ;\
	openssl rsa -noout -modulus -in server.key | openssl md5) \
	| uniq

Il y a correspondance si la commande n’affiche qu’un seul hash (ou alors il y a eu collision md5, mais c’est rare)

Plus d’infos