<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">
  <title>Artisan Numérique</title>
  <link rel="alternate" type="text/html" href="http://artisan.karma-lab.net/node/1153"/>
  <link rel="self" type="application/atom+xml" href="http://artisan.karma-lab.net/node/1153/atom/feed"/>
  <id>http://artisan.karma-lab.net/node/1153/atom/feed</id>
  <updated>2007-10-14T18:02:04+02:00</updated>
  <entry>
    <title>Créer sa propre (mini) PKI</title>
    <link rel="alternate" type="text/html" href="http://artisan.karma-lab.net/node/1153" />
    <id>http://artisan.karma-lab.net/node/1153</id>
    <published>2007-06-28T13:15:13+02:00</published>
    <updated>2007-10-14T18:02:04+02:00</updated>
    <author>
      <name>Ulhume</name>
    </author>
    <category term="Sécurité" />
    <category term="Aucun" />
    <category term="OK" />
    <category term="Tutoriel" />
    <summary type="html"><![CDATA[<p>
  L'objectif de ce tutorial est de vous permettre de créer des certificats utilisables pour sécuriser une connection à un serveur web (https), un serveur imap (imaps) ou tout autre utilisation. L'idée est d'aller un peu plus loin que le simple certificat auto-signé en créant son propre authorité de certification (CA pour Certificate Authority). L'avantage de cette approche est qu'en important un certificat CA sur le poste client, ce dernier acceptera sans broncher tous les certificats qui seront signé du CA, sans erreur ni warnings. 
</p>
    ]]></summary>
    <content type="html"><![CDATA[<p>
  L'objectif de ce tutorial est de vous permettre de créer des certificats utilisables pour sécuriser une connection à un serveur web (https), un serveur imap (imaps) ou tout autre utilisation. L'idée est d'aller un peu plus loin que le simple certificat auto-signé en créant son propre authorité de certification (CA pour Certificate Authority). L'avantage de cette approche est qu'en important un certificat CA sur le poste client, ce dernier acceptera sans broncher tous les certificats qui seront signé du CA, sans erreur ni warnings. 
</p>
<!--break-->

	<a name='chapter_1'></a>
  <h2>Quelques bases</h2>
	
<p>
  Dés que l'on désire 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 posé sur le serveur contient une paire de clef qui vont permettre aux deux parties d'échanger en confiance des informations, dont la clef symétrique qui va servir à crypter le reste de la communication. 
</p>
<p>
  Un certificat peut très facilement être généré par le paquet <kbd>openssl</kbd>. Mais pour qu'un certificat serveur soit déclaré valide sur le client, il doit répondre à trois certains :
  <ol>
    <li>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.</li>
    <li>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 <kbD>signature invalide</kbd></li>
    <li>Le certificat doit être signé par un CA (Certificate Authority). C'est le point le plus délicat dont nous allons maintenant discuter.</li>
  </ol>
</p>
<p>
  Tout maquemement  l'une de ses régles entraine un message d'avertissement sur le navigateur client. Notre but est ici d'obtenir une connection sans aucun avertissement. 
</p>
<p>
  Revenons à la régle n°3. L'autorité de certification ou CA, est ce que l'on appelle "un tiers de confiance". En effet, comme tout le monde peut fabriquer un certificat, il est logique qu'un tiers valide que les informations que contient ce certificat son réelles.
</p>
<p>
  Le rôle de tier de confiance est joué par des sociétés commerciales et reconnues qui, en tant que CA, signent vos certificats.. moyennant finance. Et elles font payer relativement cher petit ce service. Donc si en tant que petite société, pour son intranet, nous voulons un certificat signé, il faut soit payer, soit s'auto-proclamer CA... 
</p>
<p>
  Bien évidemment, ce n'est pas aussi simple. Les certificats sont un maillon important de la sécurisation des transactions par internet. La signature du CA assure par exemple au client d'une banque qu'il est bien sur SA banque (c'est écrit dans le certificat). Le client internet, le navigateur web par exemple, va donc vérifier que le certificat du site que vous chercher à consulter est légitimenent signé. 
</p>
<p>
  Pour faire cela, le navigateur a connais une cinquantaine de CA reconnus. C'est donc dans cette liste qu'il va vérifier que le certificat de votre banque est correctement signé par un CA. Cependant, pour notre salut, tout client SSL permet à l'utilisateur de rajouter son propre CA. 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 ce CA maison, seront valides et le navigateur ne couinera plus, les 3 règles seront satisfaites.
</p>


	<a name='chapter_2'></a>
  <h2>fabrication d'une petite PKI</h2>
	
<p>
  Nous allons très modestement faire notre petite PKI à la mano. La PKI (Private Key Infrastructure) vas nous permettre de générer et de signer à la chaine nos certificats. J'utilise le mot <kbd>pki</kbd> pour rire car une <i>vraie</i> 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 CA et sa base de certificats ce qui n'est pas si mal. 
</p>
<p>
  Première étape créer un dossier qui contiendra nos données, disons <kbd>/root/pki</kbd>. 
  
  <div class='code-block code-block-fragment'>
  <div class='container'>
  <a target="blank" href="http://pwet.fr/man/linux/commandes/mkdir"><span class="kw2">mkdir</span></a> <span class="sy0">/</span>root<span class="sy0">/</span>pki<br />
<span class="kw3">cd</span> <span class="sy0">/</span>root<span class="sy0">/</span>pki
  </div>
  
  </div>
</p>
<div class='inline-box attention'>
   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 !!
</div>
<p>
  Maintenant nous allons créer le pki à proprement parler. 
  
  <div class='code-block code-block-fragment'>
  <div class='container'>
  <a target="blank" href="http://pwet.fr/man/linux/commandes/mkdir"><span class="kw2">mkdir</span></a> db<br />
<a target="blank" href="http://pwet.fr/man/linux/commandes/mkdir"><span class="kw2">mkdir</span></a> config<br />
<a target="blank" href="http://pwet.fr/man/linux/commandes/mkdir"><span class="kw2">mkdir</span></a> db<span class="sy0">/</span>ca.db.certs<br />
<span class="kw3">echo</span> <span class="st0">'01'</span><span class="sy0">&gt;</span> db<span class="sy0">/</span>ca.db.serial<br />
<a target="blank" href="http://pwet.fr/man/linux/commandes/cp"><span class="kw2">cp</span></a> <span class="sy0">/</span>dev<span class="sy0">/</span>null db<span class="sy0">/</span>ca.db.index
  </div>
  
  </div>
</p>

<p>
  Maintenant nous allons créer le fichier <kbd>config/ca.config</kbd>
  
  <div class='code-block code-block-fragment'>
  <div class='container'>
  [ ca ]<br />
default_ca &nbsp; &nbsp; &nbsp;= CA_own<br />
<br />
[ CA_own ]<br />
dir &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; = /root/pka/db<br />
certs &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; = /root/pka/db<br />
new_certs_dir &nbsp; = /root/pka/db/ca.db.certs<br />
database &nbsp; &nbsp; &nbsp; &nbsp;= /root/pka/db/ca.db.index<br />
serial &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;= /root/pka/db/ca.db.serial<br />
RANDFILE &nbsp; &nbsp; &nbsp; &nbsp;= /root/pka/db/ca.db.rand<br />
certificate &nbsp; &nbsp; = /root/pka/ca/ca.crt<br />
private_key &nbsp; &nbsp; = /root/pka/ca/ca.key<br />
default_days &nbsp; &nbsp;= 3000<br />
default_crl_days = 30<br />
default_md &nbsp; &nbsp; &nbsp;= md5<br />
preserve &nbsp; &nbsp; &nbsp; &nbsp;= no<br />
policy &nbsp;= policy_anything<br />
<br />
[ policy_anything ]<br />
countryName &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; = optional<br />
stateOrProvinceName &nbsp; &nbsp; = optional<br />
localityName &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;= optional<br />
organizationName &nbsp; &nbsp; &nbsp; &nbsp;= optional<br />
organizationalUnitName &nbsp;= optional<br />
commonName &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;= supplied<br />
emailAddress &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;= optional
  </div>
  
  </div>
</p>

<p>
  Tout est en place, nous allons maintenant générer la clef privée de notre CA maison. 
  
  <div class='code-block code-block-fragment'>
  <div class='container'>
  <a target="blank" href="http://pwet.fr/man/linux/commandes/mkdir"><span class="kw2">mkdir</span></a> ca<br />
openssl genrsa -des3 -out ca<span class="sy0">/</span>ca.key <span class="nu0">1024</span>
  </div>
  
  </div>
</p>
<div class='inline-box attention'>
  Juste un détail, <kbd>toto</kbd> n'est <i>pas</i> 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... Et ceci est valable pour tout les mots de passe...
</div>
<div class='inline-box attention'>
 Attention à ne pas perdre le mot de passe qui va vous être demandé, il vous servira pour chaque nouvelle signature de certificat.
</div>

<p>
  La clef du 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 <img src="http://artisan.karma-lab.net/sites/all/modules/contrib/smileys/packs/crystal/wink2.gif" title="Wink" alt="Wink" class="smiley-content"/>. Auto-signé veut dire que le certificat est utilisé pour se signer lui-même. 
  
  <div class='code-block code-block-fragment'>
  <div class='container'>
  openssl req -new -x509 -days <span class="nu0">3000</span> -key ca<span class="sy0">/</span>ca.key -out ca<span class="sy0">/</span>ca.crt
  </div>
  
  </div>
</p>

<p>
  A ce stade, notre CA 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.
  
  <div class='code-block code-block-fragment'>
  <div class='container'>
  openssl x509 -in ca<span class="sy0">/</span>ca.crt -outform DER -out ca<span class="sy0">/</span>ca.der
  </div>
  
  </div>
</p>
<div class='inline-box attention'>
  Le fichier <kbd>ca.der</kbd> est le seul fichier que vous donnerez aux utilsateurs. Tout le reste doit être strictement privé !!
</div>

<p>
  A ce stade notre pki est fonctionelle, il ne nous reste plus qu'à générer notre premier certificat. 
</p>

	<a name='chapter_3'></a>
  <h2>Génération d'un certificat</h2>
	
<p>
  La procédure est assez simple. Dans la mesure où un certificat est lié à un nom de machine (par exemple le ceritificat https pour <kbd>www.monsite.fr</kbd>), j'ai pris le parti de donner ce nom aux fichiers générés (par exemple, <kbd>https.www.monsite.fr.crt</kbd> pour le certificat).
</p>
<p>
  Pour avoir un certificat en régle, nous devons d'abord, comme pour le CA, générer une clef. A la différence du CA, nous ne demandons pas de mot de passe. 
  
  <div class='code-block code-block-fragment'>
  <div class='container'>
  openssl genrsa -out https.www.monsite.fr.key <span class="nu0">1024</span>
  </div>
  
  </div>
</p>

<p>
  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 en signant notre demande de certificat pour ainsi 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 edictée plus haut. Dans notre exemple, lorsque openssl demandera <kbd>YOUR name</kbd>, vous répondrez <kbd>www.monsite.fr</kbd>
  
  <div class='code-block code-block-fragment'>
  <div class='container'>
  openssl req -days <span class="nu0">365</span> -new -key https.www.monsite.fr.key -out https.www.monsite.fr.csr
  </div>
  
  </div>
</p>

<p>
  Nous allons maintenenant utiliser notre pki et notre CA pour signer cette demande et obtenir notre certificat :
  
  <div class='code-block code-block-fragment'>
  <div class='container'>
  openssl ca -config <span class="sy0">/</span>root<span class="sy0">/</span>pki<span class="sy0">/</span>config<span class="sy0">/</span>ca.config -out https.www.monsite.fr.crt -infiles https.www.monsite.fr.csr
  </div>
  
  </div>
</p>

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

  <div class='code-block code-block-fragment'>
  <div class='container'>
  openssl x509 -text -in https.www.monsite.fr.crt
  </div>
  
  </div>
</p>
<p>
  Côté stockage, la bonne pratique semble vouloir que les certificats (.key, .csr et .crt) soient stockés dans le dossier <kbd>/etc/ssl/{application}</kbd> où <kbd>application</kbd> est par exemple <kbd>apache</kbd> pour le web, <kbd>cyrus</kbd> pour l'imap, etc...
</p>


	<a name='chapter_4'></a>
  <h2>Installation des certificats sur les serveurs</h2>
	
<p>
  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 <a href="/securiser-un-serveur-apache">Apache</a>, <a href="/mise-en-oeuvre-de-cyrus-imapd">Cyrus</a>, ou tout autre système pour que cela fonctionne en SSL. 
</p>


	<a name='chapter_5'></a>
  <h2>Installation du certificat CA sur un client</h2>
	
<p>
  L'idée générale est de fournir d'une manière ou d'une autre le fichier <kbd>ca.der</kbd> (et aucun autre !!) au client. Ensuie il y a autantde méthodes que de client. 
</p>
<h3>Pour FireFox & Thunderbird</h3>
<p>
  Aller dans <kbd>edit/preferences</kbd>, dans l'onglet <kbd>Advanced</kbd>, cliquer sur <kbd>view certificates</kbd>, puis aller sur l'onglet <kbd>Authorities</kbd>, cliquer sur <kbd>Import</kbd>. Aller chercher le fichier .der et validez. Cocher <kbd>Trust this CA to identify web sites</kbd>. Cocher aussi l'équivalent pour le mail pour thunderbird, puis valider. Le certificat CA devrait apparaître dans la liste. Faites OK pour sortir.
</p>

<h3>Pour Konqueror & KMail</h3>
<p>
  Aller dans <kbd>Configuration/Configurer Konqueror</kbd>. Aller dans la section <kbd>Cryptographie</kbd>, dans l'onglet <kbd>Signataires</kbd>, cliquer sur <kbd>import</kbd>. Aller chercher le fichier .der et validez. Authorisez ou nom l'utilisation du certificat dans KMail puis valider pour sortir.
</p>
<h3>Pour IE 7</h3>
<p>
  Aller dans <kbd>Outils/Options Internet</kbd>, Onglet <kbd>contenu</kbd>, cliquer sur <kbd>Certificats</kbd>. Aller dans l'onglet <kbd>Authorités principales de confiance</kbd>, et cliquer sur <kbd>Importer..</kbd>. Suivre l'assistant et aller chercher le fichier .der (contrairement à ce qui est indiqué, il l'accepte...). Ceci fait valider. 
</p>
<h3>Pour subversion</h3>
<p>
  Placer le fichier ca.crt dans le dossier <kbd>/etc/ssl/ca</kbd>. Puis modifier le fichier <kbd>/etc/subversion/servers</kbd> comme suit :
  
  <div class='code-block code-block-fragment'>
  <div class='container'>
  ssl-authority-files = <span class="sy0">/</span>etc<span class="sy0">/</span>ssl<span class="sy0">/</span>ca<span class="sy0">/</span>ca.crt
  </div>
  
  </div>
</p>    ]]></content>
  </entry>
</feed>
