Note: Ce tuto est très vieux et risque de ne pas fonctionner correctement à l’heure où vous lisez ces lignes.
Par Serianox le lundi 10 mai 2010, 14:21 – (Lien permanent de la version originelle de Serianox)
Modifié par Zertrin, le dimanche 15 avril 2012.
Petite mise à plat des notes que j’avais prises lorsque je m’étais amusé avec OpenSSL, ou comment mettre en place une petite autorité de certification auto-signée.
Ceci n’est pas un guide, mais plutôt un petit walkthrough pour les personnes qui connaissent déjà bien les principes.
Procédure en partant de zéro : création d’une autorité de certification auto-signée et émission d’un certificat serveur signé par cette autorité :
Tout d’abord, mettons en forme nos répertoires
#~ mkdir -p /etc/ssl/local; cd /etc/ssl/local
Puis créons différents sous-répertoires, à savoir:
- certs : pour les certificats serveur
- conf : pour les fichiers de configuration
- keys : pour les clefs serveur
- newcerts : pour les certificats nouvellement crées
- private : pour le certificat racine et sa clef
- public : pour la clef publique
- requests : pour les requêtes
#~ mkdir {certs,conf,keys,newcerts,private,public,requests}
Puis il nous reste à générer deux fichiers dans cette racine pour pouvoir commencer
#~ touch index.txt #~ echo "00" > serial
Nous allons ensuite générer nos fichiers de configuration.
Le premier, conf/ca.cnf
est celui utilisé lors de la génération de notre autorité de certification auto-signée
[req] default_days = 3650 default_keyfile = private/ca.key.new encrypt_key = yes default_bits = 4096 distinguished_name = rdn prompt = no req_extensions = req_exts x509_extensions = x509_exts [rdn] countryName = <> stateOrProvinceName = <> localityName = <> organizationName = <> organizationalUnitName = <> emailAddress = <> commonName = <> [req_exts] [x509_exts] #nsComment = subjectKeyIdentifier = hash authorityKeyIdentifier = keyid,issuer:always issuerAltName = issuer:copy basicConstraints = critical,CA:TRUE,pathlen:0 keyUsage = keyCertSign, cRLSign subjectAltName = email:copy
Le second, conf/openssl.cnf
représente les contraintes qui doivent être validées par toute requêtes avant d’être signées par l’autorité.
[ca] default_ca = CA_default [CA_default] dir = . certs = $dir/certs new_certs_dir = $dir/newcerts database = $dir/index.txt certificate = $dir/private/ca.crt serial = $dir/serial private_key = $dir/private/ca.key default_days = 365 default_md = sha1 preserve = no policy = policy_match x509_extensions = x509_exts copy_extensions = copy [policy_match] countryName = match organizationName = optional commonName = supplied emailAddress = optional [x509_exts] subjectKeyIdentifier = hash authorityKeyIdentifier = keyid,issuer:always issuerAltName = issuer:copy basicConstraints = critical,CA:FALSE keyUsage = digitalSignature, nonRepudiation, keyEncipherment
Le dernier, conf/server.cnf
, est notre certificat de test qui sera signé par notre autorité. Il faut ensuite l’adapter à chaque usage.
[req] default_days = 365 default_keyfile = keys/server.key.new encrypt_key = yes default_bits = 2048 distinguished_name = rdn prompt = no req_extensions = req_exts x509_extensions = req_exts [rdn] countryName = <> stateOrProvinceName = <> localityName = <> organizationName = <> organizationalUnitName = <> emailAddress = <> commonName = <> [req_exts] subjectAltName = @alt_names [alt_names] email.1 = copy DNS.1 = <> DNS.2 = <>
Maintenant, commençons nos opérations.
Nous générons notre autorité de la façons suivante.
#~ openssl req -new -x509 -days 3650 -config conf/ca.cnf -out newcerts/ca.crt
Nous générons ensuite une requête pour notre serveur.
#~ openssl req -new -config conf/server.cnf -out requests/server.csr
Puis nous la vérifions.
#~ openssl req -in requests/server.csr -noout -text
Si tout semble en ordre, nous la signons
#~ openssl ca -config conf/openssl.cnf -days 365 -in requests/server.csr -out newcerts/server.crt
Une fois signé, on peut déplacer le nouveau certificat et renommer sa clef privée pour mettre en prod
#~ mv newcerts/server.crt certs/server.crt #~ mv keys/server.key.new keys/server.key
Procédure pour mettre à jour un certificat existant :
Pour me faciliter les choses, j’ai préparé un petit script bash qui me permet de faire les choses dans l’ordre (à adapter bien évidemment selon votre configuration) : Voir en Annexe
Pour commencer, on édite le fichier de configuration propre à l’émission du certificat (le cas échéant, par exemple ajout de sous-domaines DNS…) :
#~ cd /etc/ssl/local/ #~ vim conf/server.cnf
On crée ensuite une nouvelle requête à partir du fichier de conf :
#~ openssl req -new -config conf/server.cnf -out requests/server.csr
On vérifie avant toute chose que la demande correspond bien à ce qu’on veut :
#~ openssl req -in requests/server.csr -noout -text
Si tout est bon, on commence par révoquer le certificat émis précedemment :
#~ openssl ca -config conf/openssl.cnf -revoke certs/server.crt
On signe ensuite la demande émise précédemment :
#~ openssl ca -config conf/openssl.cnf -days 365 -in requests/server.csr -out newcerts/server.crt
On déplace ensuite le nouveau certificat et sa clef dans les dossiers idoines :
#~ mv keys/server.key keys/server.key.bak #~ mv keys/server.key.new keys/server.key #~ mv certs/server.crt certs/server.crt.bak #~ mv newcerts/server.crt certs/server.crt
Si nécessaire, on retire le mot de passe de la clef privée serveur :
#~ openssl rsa -in keys/server.key -out keys/server.key.insecure
Quelques manipulations supplémentaires
- Suppression d’un mot de passe sur une clef
#~ openssl rsa -in keys/server.key -out keys/server.key.insecure
- Ajout d’un mot de passe pour une clef
#~ openssl rsa -in keys/server.key.insecure -des3 -out keys/server.key
- Conversion d’un
PEM
enDER
#~ openssl x509 -in certs/server.crt -inform pem -out certs/server.der -outform der
- Conversion d’un
DER
enPEM
#~ openssl x509 -in certs/server.der -inform der -out certs/server.pem -outform pem
- Génération d’un certificat serveur avec la clef privée incluse dedans
#~ cat certs/server.crt keys/server.key > server.pem
Enfin, quelques opérations de signature.
- Exporter la partie publique d’une clef
#~ openssl rsa -in keys/server.key -pubout -out pub.key
- Chiffrer avec la clef publique
#~ openssl rsautl -encrypt -in file -inkey pub.key -out file.sec
- Déchiffrer avec la clef privée
#~ openssl rsautl -decrypt -in file.sec -inkey keys/server.key -out file
- Hacher un gros fichier
#~ openssl dgst sha512 -out file.dst file
- Signer un fichier
#~ openssl rsautl -sign -in file -inkey keys/server.key -out file.sgn
- Verifier un hash
#~ openssl rsautl -verify -in file.sgn -pubin -inkey pub.key -out file
Et voila, c’est tout. En conclusion de cette longue énumération, je rappelle à toutes les personnes qui lisent ce genre de ligne que mettre en place une autorité de certification ne consiste pas seulement en générer les fichiers nécessaires ; avoir une politique de sécurité consiste déjà à protéger convenablement ses clefs privées.
Annexe
Voici le script bash que j’utilise pour mettre à jour mon certificat quand cela est nécessaire (renouvellement, ajout de sous-domaines…) :
#!/bin/bash cont(){ read -p "Continue? [yY to continue] " -n 1 if [[ ! $REPLY =~ ^[Yy]$ ]] then exit 1 fi echo } cd /etc/ssl/local/ echo "####### EDITING conf/server.cnf #######" vim conf/server.cnf echo "####### CREATING request/server.csr #######" cont openssl req -new -config conf/server.cnf -out requests/server.csr echo "####### REVIEW of request/server.csr #######" cont openssl req -in requests/server.csr -noout -text echo "####### REVOKING certs/server.crt #######" echo "!!!!!!! IMPORTANT : if you continue, the current certificate WILL be revoked !!!!!!!" cont openssl ca -config conf/openssl.cnf -revoke certs/server.crt echo "####### SIGNING of conf/server.csr #######" cont openssl ca -config conf/openssl.cnf -days 365 -in requests/server.csr -out newcerts/server.crt echo "####### MOVING new key #######" cont mv keys/server.key keys/server.key.bak mv keys/server.key.new keys/server.key echo "####### MOVING new cert #######" cont mv certs/server.crt certs/server.crt.bak mv newcerts/server.crt certs/server.crt echo "####### REMOVING password of keyfile #######" cont openssl rsa -in keys/server.key -out keys/server.key.insecure