Créer sa propre (mini) PKI
Le 12 January 2009 à 12:00.

Pour sécuriser une connection à un serveur web (https), un serveur imap (imaps) ou tout autre client utilisant SSL ou TLS, nous avons besoin d'un certificat. Dans une première approche il est possible d'utiliser des certificat dits "auto-signés". Générés très facilement, il sont très pratique pour développer et tester un site sécurisé mais beaucoup moins s'agissant d'une utilisation régulière et publique, principalement à cause des avertissements de sécurité qu'ils génèrent sur l'application cliente. L'autre option est alors d'acheter un certificat auprès d'un tiers de confiance. Certificat qui vous permettra à votre tour d'en générer d'autres qui cette fois seront acceptés sans erreur.

La troisième voie développée ici, entre l'auto-signature et l'achat, consiste à créer sa propre autorité certifiante qui, une fois importée, par exemple dans un navigateur, se comportera exactement de la même manière que si vous l'aviez achetée. Au delà de la compréhension technique des mécanismes mis en jeu, cette approche est plutôt bien adaptée à une petite structure qui n'a pas le goût de payer un certificat et pour qui distribuer ou pré-installer une autorité ne pose pas de problèmes (nombre restreint d'utilisateurs, postes pré-installés, etc.).

Quelques bases

Dés que l'on souhaite mettre en oeuvre une connection cryptée par SSL, que ce soit pour Cyrus (IMAPS) ou pour Apache (HTTPS), il est nécessaire d'avoir un certificat. Ce certificat installé sur le serveur contient une paire de clef qui vont permettre aux deux parties de mettre en place un échange chiffré. Une des informations échangée à ce stade est une autre clef qui va servir quant à elle à chiffrer, par un algorithme dit "symétrique", le reste de la communication. La raison de ce changement de clef tient à ce que le chiffrement asymétrique est plus demandeur en ressources, mais aussi plus sécurisé, que sa contrepartie symétrique. Ce protocole permet en quelque sorte d'arriver au meilleur des deux mondes.

Un certificat peut très facilement être généré en utilisant les outils du paquet openssl. Mais pour qu'un certificat serveur soit déclaré valide sur le client il doit répondre à trois règles, et tout manquement à l'une de ces règles entraîne l'affichage d'un message d'avertissement sur le navigateur client.

  1. Le certificat doit contenir le nom du site qu'il sécurise (ex. www.mon_site.fr). Si ce n'est pas le cas, le navigateur protestera que le certificat ne provient pas de la bonne adresse.
  2. Le certificat doit contenir une signature fiable. Si ce n'est pas le cas, certain navigateurs se contenterons de pleurer un peu, d'autres, comme FireFox, bloquera l'accès avec un signature invalide
  3. Le certificat doit être signé par un AC (Autorité de Certification) ou par un certificat qui lui même est signée par un AC. Et c'est ici le point le plus délicat dont nous allons maintenant discuter.

Revenons à la règle n°3. Un certificat doit être signé à un moment ou à un autre par ce que l'on appelle "un tiers de confiance". Sur Internet, le rôle de tiers de confiance est joué par des sociétés commerciales que l'on paye grassement juste pour signer un certificat d'AC à notre nom et qui va nous permettre de générer nos certificats... Et si en tant que petite société, pour son intranet par exemple, nous désirons nous débarrasser des messages d'erreur du navigateur, il faut soit payer sa dîme, soit s'auto-proclamer AC...

Bien évidemment, ce n'est pas aussi simple. Les certificats sont un maillon important de la sécurisation des transactions par internet. La signature par un AC assure par exemple au client d'une banque qu'il est bien sur SA banque (c'est écrit dans le certificat). Un navigateur web, par exemple, va donc vérifier que le certificat du site que vous cherchez à consulter est légitimement signé. Plus exactement il va vérifier la validité de la chaîne des signatures. Il va commencer par regarder si le certificat est valide (non périmé, réprouvé, etc.), puis si le certificat est signé par une AC de confiance. Si c'est le cas il s'arrête là, sinon, il regarder qui a signé le certificat de cette AC, si son certificat est valide, s'il est signé par une AC de confiance, etc. Pour faire cela, tout navigateur connaît donc en standard la série complète de ces AC "de confiance".

Cependant, pour notre salut, tout client prenant en charge SSL permet à l'utilisateur de rajouter sa propre AC. C'est une action volontaire qui ne peut être automatisée. Vous allez ainsi fournir à vos utilisateur un fichier dit "DER" qu'il va importer dans son logiciel (FireFox, IE, etc..). Ceci fait, tout les certificats que vous signerez de cette AC maison, seront valides et le navigateur ne couinera plus, les 3 règles seront satisfaites.

Fabrication d'une petite PKI

Nous allons très modestement faire notre petite PKI à la mano. Cette PKI (Private Key Infrastructure) vas nous permettre de générer et de signer à la chaîne nos certificats. J'utilise le mot pki pour rire car une vraie PKI est un ensemble complexe comprenant non seulement la génération des certificats, mais aussi et entre autre leur révocation. Cependant, nous disposerons bientôt d'une mini-pki avec son AC et sa base de certificats ce qui n'est déjà pas si mal.

Première étape créer un dossier qui contiendra nos données, disons /root/pki, et la base de données des certificats :

# Création de l'infrastructure
root#mkdir /root/pki
root#cd /root/pki
root#mkdir -p db/ca.db.certs
root#mkdir config
root#mkdir certificats
 
# Initialisation des numéros de séries à 1
root#echo '01'> db/ca.db.serial
 
# Initialisation de l'index des certificats
root#cp /dev/null db/ca.db.index
root# 
initialisation de la base de données

Ce dossier est sensible, il contient des donnes importantes qui permettrait, si son contenu venait à \"fuiter\", n'importe qui serait en capacité de créer des certificats à votre nom !!

Maintenant nous allons créer le fichier de configuration config/ca.config qui va permettre à openssl d'utiliser notre nouvelle base :

[ ca ]
default_ca      = CA_own

[ CA_own ]
dir             = /root/pki/db
certs           = /root/pki/db
new_certs_dir   = /root/pki/db/ca.db.certs
database        = /root/pki/db/ca.db.index
serial          = /root/pki/db/ca.db.serial
RANDFILE        = /root/pki/db/ca.db.rand
certificate     = /root/pki/certificats/ca.crt
private_key     = /root/pki/certificats/ca.key
default_days    = 3000
default_crl_days = 30
default_md      = md5
preserve        = no
policy  = policy_anything

[ policy_anything ]
countryName             = optional
stateOrProvinceName     = optional
localityName            = optional
organizationName        = optional
organizationalUnitName  = optional
commonName              = supplied
emailAddress            = optional
configuration OpenSSL

Tout est en place, nous allons maintenant générer la clef privée de notre AC maison.

root#openssl genrsa -des3 -out certificats/ca.key 1024
Generating RSA private key, 1024 bit long modulus
.........................++++++
..........++++++
e is 65537 (0x10001)
Enter pass phrase for certificats/ca.key:toto
Verifying - Enter pass phrase for certificats/ca.key:toto
root#
root# 
création de la clef privée de la AC

Juste un détail, toto n'est pas un mot de passe intelligent... Préférez un mot de passe à 12 caractères contenant des chiffres, des symboles, des lettres, et des variations de majuscules/minuscules, et surtout, ne voulant rien dire !! N'utilisez pas non plus de générateur par internet ou de vérificateur de solidité de mot de passe par internet. Rien de plus idiot que de fournir ou de demander votre mot de passe stratégique à un inconnu... Tout ceci est d'ailleurs valable pour tout les mots de passe...
Attention aussi à ne pas perdre le mot de passe qui va vous être demandé, il vous servira pour chaque nouvelle signature de certificat.

La clef de notre CA étant générée, nous allons créer un certificat "auto-signé" valable pour 3000 jours (cela nous laisse un peu de marge Wink. Auto-signé veut dire que le certificat est utilisé pour se signer lui-même.

root#openssl req -utf8 -new -x509 -days 3000 -key cacertificatsca.key -out certificats/ca.crt
Enter pass phrase for certificats/ca.key:toto
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) [GB]:FR
State or Province Name (full name) [Berkshire]:L'île aux enfants
Locality Name (eg, city) [Newbury]:Nuages
Organization Name (eg, company) [My Company Ltd]:Casimir SARL
Organizational Unit Name (eg, section) []:Entertainement
Common Name (eg, your name or your server's hostname) []:www.casimir.fr
Email Address []:
root#
root# 
création du certificat CA

Les informations rentrées ici n'ont que peut d'importance mais autant y mettre des choses justes. A ce stade, notre AC est complet, nous allons juste générer un fichier de plus, le "DER". C'est, comme nous l'avons vu, lui que nous allons fournir au clients (navigateur web entre autre) pour que la 3ième règle soit satisfaite et que le client ne couine plus pour tous les futurs certificats générés.

root#openssl x509 -in certificats/ca.crt -outform DER -out certificats/ca.der
root# 

Le fichier ca.der est le seul fichier que vous donnerez aux utilisateurs. Tout le reste doit être strictement privé !!

A ce stade notre pki est fonctionnelle, il ne nous reste plus qu'à générer notre premier certificat serveur.

Génération d'un certificat

La procédure est assez simple. Dans la mesure où un certificat est lié à un nom de machine (par exemple le certificat https pour www.casimir.fr), j'ai pris le parti de donner ce nom aux fichiers générés (par exemple, https.www.casimir.fr.crt pour le certificat).

Pour avoir un certificat en règle, nous devons d'abord, comme pour l'AC, générer une clef. A la différence du AC, nous ne demandons pas de mot de passe.

root#openssl genrsa -out certificats/https.www.casimir.fr.key 1024
Generating RSA private key, 1024 bit long modulus
............++++++
...........++++++
e is 65537 (0x10001)
root# 
génération de la clef du certificat

L'étape suivante change un peu. Comme nous devons faire signer notre certificat, nous allons générer un ficher intermédiaire appelé CSR pour Certificate Signature Request (ou Demande de Signature de Certificat). Ce fichier contient déjà tout ce qu'un certificat contiendra sauf la signature du CA. C'est là qu'intervient notre tiers de confiance qui, en signant notre demande de certificat, nous permet d'obtenir en retour un certificat valide. La seule chose que nous devons donner comme information est le nom de la machine. C'est très important car sans cela, nous violerions la règle n°2 donnée plus haut. Dans notre exemple, lorsque openssl demandera YOUR name, vous répondrez www.casimir.fr, et ce n'est pas la peine de rajouter un mot de passe.

root#openssl req -days 365 -new -key certificats/https.www.casimir.fr.key -out certificats/https.www.casimir.fr.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) [GB]:FR
State or Province Name (full name) [Berkshire]:L'île aux enfants
Locality Name (eg, city) [Newbury]:Nuages
Organization Name (eg, company) [My Company Ltd]:Casimir SARL
Organizational Unit Name (eg, section) []:Entertainement
Common Name (eg, your name or your server's hostname) []:www.casimir.fr
Email Address []:
 
Please enter the following 'extra' attributes
to be sent with your certificate request
A challenge password []:
An optional company name []:
root#
root# 
Demande d'un nouveau certificat

Nous allons maintenant utiliser notre PKI et notre CA pour signer cette demande et obtenir notre certificat final :

root#openssl ca -config config/ca.config -out https.www.casimir.fr.crt -infiles certificats/https.www.casimir.fr.csr
cats/https.www.casimir.fr.crt -infiles certificats/https.www.casimir.fr.csr
Using configuration fromconfig/ca.config
Enter pass phrase for /root/pki/certificats/ca.key:
Check that the request matches the signature
Signature ok
The Subject's Distinguished Name is as follows
countryName :PRINTABLE:'FR'
stateOrProvinceName :ASN.1 12:'L'\0xFFFFFFC3\0xFFFFFF83\0xFFFFFFC2\0xFFFFFFAEle aux enfants'
localityName :PRINTABLE:'Nuages'
organizationName :PRINTABLE:'Casimir SARL'
organizationalUnitName:PRINTABLE:'Entertainement'
commonName :PRINTABLE:'www.casimir.fr'
emailAddress :IA5STRING:''
Certificate is to be certified until Mar 31 10:22:44 2017 GMT (3000 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
root#
root# 
Génération du certificat serveur

Voilà, vous avez maintenant un certificat tout neuf. Vous pouvez en vérifier le contenu par la commande :

root#openssl x509 -text -in certificats/https.www.casimir.fr.crt
Certificate:
Data:
Version: 1 (0x0)
Serial Number: 1 (0x1)
Signature Algorithm: md5WithRSAEncryption
Issuer: C=FR, ST=L'\xC3\x83\xC2\xAEle aux enfants, L=Nuages, O=Casimir SARL, OU=Entertainement, CN=http://www.casimir.fr/emailAddress=
Validity
Not Before: Jan 12 10:22:44 2009 GMT
Not After : Mar 31 10:22:44 2017 GMT
Subject: C=FR, ST=L'\xC3\x83\xC2\xAEle aux enfants, L=Nuages, O=Casimir SARL, OU=Entertainement, CN=www.casimir.fr/emailAddress=
Subject Public Key Info:
Public Key Algorithm: rsaEncryption
RSA Public Key: (1024 bit)
Modulus (1024 bit):
00:a6:09:11:5b:9a:28:cf:b9:a0:0f:17:86:45:9b:
...
0d:0c:99:87:4a:5b:15:ef:ff
Exponent: 65537 (0x10001)
Signature Algorithm: md5WithRSAEncryption
2a:50:4a:3d:f2:a0:b7:68:1c:62:54:24:3f:13:81:be:db:20:
...
9d:18
-----BEGIN CERTIFICATE-----
MIICyjCCAjMCAQEwDQYJKoZIhvcNAQEEBQAwgbAxCzAJBgNVBAYTAkZSMR0wGwYD
...
bt6uImb9n7Xx9dqVUr5dd29E4fh0KKqBXWdWkStw73AP3snEo8xePf5bWladGA==
-----END CERTIFICATE-----
root# 
Vérification du certificat

Automatisation

Pour automatiser tout cela, vous pouvez utiliser ce script. La commande ./pki generate fabrique un dépôt en ~/.pki et ./pki generat génère des certificats. Lancez ./pki --help pour plus d'informations.

Installation des certificats

Une fois nos certificats générés, il ne nous reste plus qu'à déplacer les 3 fichiers là où ils seront utiles et de paramétrer Apache, Cyrus, ou tout autre système pour que cela fonctionne en SSL.

La bonne pratique dans le domaine semble vouloir que les certificats (.key, .csr et .crt) soient stockés dans le dossier /etc/ssl/{application}application est par exemple apache pour le web, cyrus pour l'imap, etc...

Installation du certificat de l'AC sur un client

L'idée générale est de fournir d'une manière ou d'une autre le fichier ca.der (et aucun autre !!) au client. Ensuite il y a autant de méthodes que de client.

Pour FireFox & Thunderbird

Aller dans edit/preferences, dans l'onglet Advanced, cliquer sur view certificates, puis aller sur l'onglet Authorities, cliquer sur Import. Aller chercher le fichier .der et validez. Cocher Trust this CA to identify web sites. Cocher aussi l'équivalent pour le mail pour thunderbird, puis valider. Le certificat CA devrait apparaître dans la liste. Faites OK pour sortir.

Pour Konqueror & KMail

Aller dans Configuration/Configurer Konqueror. Aller dans la section Cryptographie, dans l'onglet Signataires, cliquer sur import. Aller chercher le fichier .der et validez. Autorisez ou nom l'utilisation du certificat dans KMail puis valider pour sortir.

Pour IE 7

Aller dans Outils/Options Internet, Onglet contenu, cliquer sur Certificats. Aller dans l'onglet Autorités principales de confiance, et cliquer sur Importer... Suivre l'assistant et aller chercher le fichier .der (contrairement à ce qui est indiqué, il l'accepte...). Ceci fait valider.

Pour subversion

Placer le fichier ca.crt dans le dossier /etc/ssl/ca. Puis modifier le fichier /etc/subversion/servers comme suit :

ssl-authority-files = /etc/ssl/ca/ca.crt

Conclusion

Bien évidement cette technique ne remplacera pas une AC officielle et ne vous évitera pas, par exemple pour du commerce en ligne, de payer votre certificat. Mais dans pas mal de cas touchant de près ou de loin à l'intranet pour un nombre réduit d'utilisateurs, cette solution marche à merveille tout en étant simple à mettre en oeuvre.

Commentaires

Anonymous, le 8 septembre, 2008 - 16:04

Un sans fautes !

C'est clair et ... ca marche du premier coup !

Bravo et merci

Anonymous, le 11 janvier, 2009 - 22:55

Un grand merci

Fabrice, le 12 janvier, 2009 - 13:41

Un très bon article comme d'habitude Wink.
Reste encore une voie ... ou presque. Chercher du libre sans devoir monter sa CA.
par exemple et très bien .. cacert.org.
Personnellement j'utilise les certificats émis par cette autorité pour un site pro + OWA.

Ulhume, le 12 janvier, 2009 - 18:24

Pour l'instant CACerts semble en cours d'intégration dans certains navigateurs :
http://wiki.cacert.org/wiki/InclusionStatus

Et je ne sais pas si c'est fait exprès, mais il en manque quelques-un, et non des moindre : IE, Opéra et Konqueror.

En somme, le projet est très intéressant, merci pour ce pointeur, mais il a encore besoin de maturité pour être utilisé en remplacement d'un verisign. Pour l'heure, sauf si je me goure ou si le statut est faux, cela oblige importé le Ca-Root comme pour cette méthode. Et je préfère ne dépendre de personne quant je ne suis pas obligé Wink

time0ut, le 12 janvier, 2009 - 16:48

Très intéressant merci !

StandarT, le 12 janvier, 2009 - 18:35

Encore un excellent article comme les précédents sur la sécurité, c'est vraiment bien pour ceux qui veulent découvrir toutes ces notions obscures et de les "éclaircir" pour le grand public. félicitations.

Dup, le 12 janvier, 2009 - 22:59

Hehe pas tout lu encore mais tout à l'air clair et complet (oui je regarde la TV en même temps et je finirais de lire après à tête reposée Sticking out tongue)

Actuellement je suis sur Cacert et effectivement il me faut importer le CA-Root pour ne plus avoir d'avertissement. Par contre il y a une solution "professionnelle" gratuite (pour usage perso je suppose) proposé par https://www.startssl.com/?app=0

Je vais peut être migrer mon certificat chez eux pour avoir une autorité de certification pleinement intégré dans les navigateurs.

Ulhume, le 17 janvier, 2009 - 10:36

Merci pour le pointeur, je vais regarder ça. Ceci dit faudrait aussi que je regarde à l'occasion combien coûte un certificat, si ça se trouve c'est pas énorme.

Daniel, le 17 janvier, 2009 - 15:24

OVH fait des certifs à 40€ HT (http://www.ovh.com/fr/particulier/produits/ssl.xml), (400$ chez verisign).
(j'ai pas d'actions chez eux)

Ulhume, le 17 janvier, 2009 - 19:34

Ah mais y'a un petit hic : Les certificats SSL peuvent être installés sur tout domaine enregistré chez OVH

Fallait pas rêver non plus Wink

Daniel, le 17 janvier, 2009 - 15:31

Si ça en intéresse certains, je me suis fait un petit script pour créer et signer des certificats : http://ll.lairdutemps.org/linux/scripts_bash/generation_certif

Sinon, question convention, je préfère ranger mes certifs par domaine plutôt que par appli (par ex, mail.mondomaine.tld me sert pour smtps, pops, imaps & webmail en https), mais c'est une affaire de goût...

Ulhume, le 17 janvier, 2009 - 19:35

Je vais regarder cela et te chipper des trucs pour le mien Wink

http://svn.arnumeral.fr/subversion/public/tools/utilities/pki

Gemini, le 9 mars, 2009 - 13:54

Excellent ! Je me suis créé ma petite PKI et je suis en train de voir pour déjà l'intégrer à mon réseau local.

Une petite remarque/question par rapport aux chemins que tu utilises. En fouinant mon système (une Mandriva 2009.0 Wink), il m'a semblé que le bon endroit pour déposer nos fichier concernant notre CA et autre serait /etc/pki. (mettre ça dans /root me faisait dresser quelques poils dans le dos)

Je pensais notamment à /etc/pki/CA/private pour les fichiers de notre propre CA. Mais je vois qu'il y a aussi notamment /etc/pki/tls/rootcerts qui semble contenir la liste de toutes les CA connues par défaut sur notre Mandriva. (mais au format .pem. Je pensais que c'était la même chose que le .der généré dans ton tuto mais ça ne ressemble pas vraiment ... me manque encore quelques infos pour être opérationnel Glad)

Omission volontaire (en fait ces fichiers n'ont rien à faire là) ou tout simplement tu ignorais que ça existait ?

Ulhume, le 9 mars, 2009 - 16:12

Non, c'est volontaire Smiling
En fait j'utilise la même "pki" pour plusieurs serveurs et services. Donc j'ai une machine qui sert de base de génération, bien au chaud en root, et je les recopie à la main là où elles doivent être, et notamment dans le dossier que tu viens de donner.

Gemini, le 9 mars, 2009 - 22:13

Ok merci pour les précisions ! Smiling Du coup si tu as un petit peu de temps, je pourrais te suggérer de rajouter une petite partie sur le rôle de /etc/pki et quels fichiers est-on censés mettre où.

Ça m'aurait bien aidé de l'avoir Wink (et même encore maintenant car je ne fais que supputer)

Ulhume, le 10 mars, 2009 - 02:32

Rajouté à la todo Smiling

Nemrod, le 8 février, 2010 - 17:27

Que du bon.

Un peu sur le tard (plus d'un an après l'écriture de ce billet), je me permet de parler d'une IHM pas mal du tout pour gérer ses CA comme une "petite" authorité de certification : TinyCA (et TinyCA2).
C'est un frontal bien pratique, amha, à openssl pour qui veut mettre en place et gérer une PKI. Cela ne dispense pas de savoir le faire à la main mais il m'a rendu de grands services.

Ulhume, le 24 février, 2010 - 00:05

Oh bé tu fais bien d'en parler, je ne connaissais pas Smiling

Poster un nouveau commentaire

Si vous avez détecté une erreur, coquille ou bêtises du même ordre, merci de plutôt passer par le formulaire de contact
Pour vous abonner au flux des commentaires sur cet article, clickez ici.
Pour répondre à quelqu'un, utilisez plutôt le lien répondre qui se trouve en haut (ou en bas) à gauche de son commentaire.
Le contenu de ce champ sera maintenu privé et ne sera pas affiché publiquement. Si vous avez un compte gravatar, l'utilisez pour afficher votre avatar.
  • To highlight piece of code, just surround them with <code type="language"> Your code &tl;/code>>. Language can be java,c++,bash,etc... Everything Geshi support.
  • Tags HTML autorisés : <a> <em> <strong> <cite> <code> <ul> <ol> <li> <dl> <dt> <dd> <blockquote> <div> <p> <br>
  • Les lignes et les paragraphes vont à la ligne automatiquement.
  • Textual smileys will be replaced with graphical ones.
  • Les adresses de pages web et de messagerie électronique sont transformées en liens automatiquement.
  • Every instance of custom tags in the input text will be replaced with a specific tool shortcut.

Plus d'informations sur les options de formatage


Commentaires récents
Porte secrète