Utiliser GnuPG
Dans le numéro 31 de Linux Magazine, Loïc Bernable nous expliquait comment faire nos premiers pas avec GnuPG. Nous avons appris à générer nos clefs publique et privée, à gérer les signatures des gens que nous connaissons et à manipuler notre trousseau pour signer des clefs publiques et faire signer la nôtre. Dans le présent article, nous allons voir comment utiliser GnuPG pour échanger des informations et vérifier l'intégrité et la provenance de fichiers et autres messages électroniques.

L'atout principal d'applications comme GnuPG est de permettre la signature électronique. Une signature électronique est un condensé (
hash) des données en clair chiffrées avec votre clef privée. Lorsque le destinataire va recevoir les données, il va calculer le condensé et le comparer avec la signature déchiffrée grâce à votre clef publique. Si les deux condensés sont identiques, l'intégrité du message est vérifiée.

La signature apporte une autre information. Non seulement elle permet de vérifier l'intégrité des informations mais également leur provenance. En effet, comme seule votre clef publique est capable de déchiffrer la signature, celle-ci n'a pu être chiffrée que grâce à votre clef privée. Or, la paire clef publique/clef privée est intimement liée puisqu'elle est disponible sur les serveurs de clefs et sans doute signée par vos amis. Le Web of Trust garantit la provenance du message et l'identité de l'expéditeur.

Les signatures électroniques sont largement utilisées dans le monde GNU, et en particulier par des projets importants où l'utilisateur ne peut pas se permettre de compiler et d'installer des sources d'une provenance douteuse. Ainsi, sur tous les miroirs officiels proposant le
kernel Linux, vous trouverez pour chaque tarball source et chaque patch un fichier portant un suffixe .sign. Il s'agit d'une signature GnuPG/OpenPGP portant sur le fichier du même nom. Ainsi, l'utilisateur, après téléchargement de l'archive, pourra vérifier la provenance et l'intégrité des sources ou du patch avant de l'installer. Il en va de même pour pas mal d'utilitaires ou d'applications du domaine de la sécurité.


Vérifier une signature
GnuPG met à la disposition de l'utilisateur un mécanisme très simple pour vérifier une signature. Ainsi, en gardant l'exemple du kernel Linux, imaginons que vous veniez de récupérer ces deux fichiers :

patch-2.4.10.gz
patch-2.4.10.gz.sign

Le premier est le patch sur le kernel 2.4.9 pour passer au 2.4.10 et le second, le fichier signature. En réalité, le suffixe ajouté au nom du fichier n'est pas important. Ici, il s'agit de .sign mais cela aurait pu être .gpg, .asc, .auth ou même .toto ; cela n'y changerait rien. Ce qui est important, c'est le contenu du fichier :

-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.0.4 (GNU/Linux)
Comment: See http://www.kernel.org/signature.html for info

iD8DBQA7riwGyGugalF9Dw4RAkQ/AJ0UbjPs9PZDNNOzfx0Izcw+BIo8RwCglPil
pn0HzT66c8dDqcoUHvrd18Q=
=6qzl
-----END PGP SIGNATURE-----

Nous voyons clairement un marqueur de début de signature et un marqueur de fin. Tout ce qui se trouve en dehors de ces marqueurs ne sera pas traité par GnuPG. Nous avons dans ce fichier trois éléments :

- une information relative au nom du logiciel utilisé pour générer la signature ;
- un commentaire indiquant habituellement (comme ici) un lien ou une URL permettant d'obtenir des informations sur le projet d'où émane la signature ;
- la signature à proprement parler, séparée du reste par une ligne vide.

Si nous voulons vérifier la signature sur
patch-2.4.10.gz, il nous faut la clef publique associée. Pour cela, nous n'avons qu'à suivre le lien dans le commentaire du fichier de signature pour apprendre que son ID est 517D0F0E. Nous pouvons ensuite la récupérer avec :

$ gpg --recv-keys 517D0F0E
gpg: requesting key 517D0F0E from pgp.mit.edu ...
gpg: key 517D0F0E: public key imported
gpg: Total number processed: 1
gpg: imported: 1

$ gpg --list-key 517D0F0E
pub 1024D/517D0F0E 2000-10-10 Linux Kernel Archives Verification Key <ftpadmin@kernel.org>
sub 4096g/E50A8F2A 2000-10-10

A priori, il s'agit bien de la clef de la team Linux Kernel, mais comme nous sommes des gens un peu paranoïaques (juste ce qu'il faut), nous allons regarder qui a signé cette clef :

$ gpg --list-sig 517D0F0E

Dans la majorité des cas, vous obtiendrez une liste d'ID des clefs ayant servi à signer la clef 517D0F0E, mais avec la mention "[User id not found]". Ceci est parfaitement normal, nous ne possédons pas ces clefs et ne savons donc pas à qui elles appartiennent. Nous pouvons corriger ce problème avec :

$ gpg --recv-keys `gpg --list-sig 517D0F0E | par
awk 'print $2' | sed -e "s/^.*///"`

Ne vous inquiétez pas, c'est plus simple qu'il n'y paraît :

- Nous listons les signatures sur la clef
517D0F0E.
gpg --list-sig 517D0F0E

- Dans la sortie, nous ne récupérons que les ID (seconde colonne).
awk 'print $2'

- Un certain nombre d'ID sont des sous-clefs (
sub) comprenant un /. Nous éliminons ces lignes avec sed.
sed -e "s/^.*///"

- Nous obtenons donc une liste d'ID qu'il suffit d'utiliser avec gpg.
gpg --recv-keys `[...]`

Nous venons de récupérer sur le serveur de clefs par défaut toutes celles ayant servi à signer la clef de la team Linux Kernel (En fait, un certain nombre n'auront sans doute pas été récupérées en raison d'erreurs diverses.). Nous pouvons maintenant à nouveau utiliser l'option --list-sig pour lister les signatures sur la clef :

$ gpg --list-sig 517D0F0E
pub 1024D/517D0F0E 2000-10-10 Linux Kernel Archives Verification Key <ftpadmin@kernel.org>
sig 8CEA233D 2001-07-31 Thomas Morin <thomas.morin@sympatico.ca>
sig 5D8CDA7B 2000-11-10 Guus Sliepen <guus@debian.org>
sig C9E9FDB9 2001-08-13 Hank Leininger <hlein@metases.com>
sig 5E27A50E 2000-11-29 Adam VanderHook <avanderhook@capitol-college.edu>
sig 76B79F20 2000-12-26 Sebastian Wiesinger <bofh@fire-world.de>
[...]
sig 5120BEDD 2001-07-26 Jason Cook <jasonc@gnu.org>
sig F8AD8EB9 2001-06-17 Song PR. <songmailbox@yahoo.com>
sub 4096g/E50A8F2A 2000-10-10
sig 517D0F0E 2000-10-10 Linux Kernel Archives Verification Key <ftpadmin@kernel.org>

Tout cela semble de bon augure, mais si vous le désirez, vous pouvez pousser le vice jusqu'à utiliser la commande précédente sur chacun de ces ID jusqu'à arriver sur quelqu'un que vous connaissez... (Prévoyez du temps et de l'espace disque en conséquence, vous risquez de récupérer toutes les clefs existantes.)

A présent que nous avons décidé de faire un minimum confiance à la clef
517D0F0E, nous pouvons vérifier la signature sur l'archive :

$ gpg --verify patch-2.4.10.gz.sign patch-2.4.10.gz
gpg: Signature made dim 23 sep 2001 20:37:58 CEST using DSA key ID 517D0F0E
gpg: Good signature from "Linux Kernel Archives Verification Key <ftpadmin@kernel.org>"
Could not find a valid trust path to the key. Let's see whether we
can assign some missing owner trust values.

No path leading to one of our keys found.

gpg: WARNING: This key is not certified with a trusted signature!
gpg: There is no indication that the signature belongs to the owner.
gpg: Fingerprint: C75D C40A 11D7 AF88 9981 ED5B C86B A06A 517D 0F0E

La signature est vérifiée (Good signature...), mais GnuPG vous précise néanmoins qu'il n'existe pas de chemin reliant la clef utilisée à une des nôtres et qu'il ne dispose d'aucun moyen permettant de faire confiance aux personnes ayant signé la clef utilisée pour la signature de l'archive. Nous verrons tout cela un peu plus loin dans l'article. En attendant, changeons les rôles et voyons comment créer une signature pour une archive que nous diffusons.

Soit le fichier
amoi.tar.gz que nous souhaitons mettre à la disposition de tous via des serveurs HTTP ou FTP. Nous allons signer notre archive afin de prouver son origine et son intégrité :

$ gpg -a -b amoi.tar.gz
You need a passphrase to unlock the secret key for
user: "Denis XXXXX <XXXXXXXXX@xxxxxxxxxxxx.org>"
1024-bit DSA key, ID 47C5A6C8, created 2000-05-14
Enter passphrase:

L'option -a permet d'obtenir une sortie sous forme ASCII formatée de la même manière que le .sign du kernel. C'est habituellement l'option à préférer, car dans le cas contraire, nous obtiendrions une sortie binaire plus difficilement identifiable. L'option -b permet de créer une signature détachée. Nous allons obtenir un fichier appelé amoi.tar.gz.asc par défaut (asc comme ASCII). Comme nous l'avons dit précédemment, le suffixe est purement décoratif :

$ cat amoi.tar.gz.asc
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.0.6 (GNU/Linux)
Comment: For info see http://www.gnupg.org

iD8DBQA7sGKqobIuzUPEs8gRAuoXAJ9cQZ83JQlw8MqlPEaDDxpheXGOAACgxpfo
kCBiGlsbnUfo3YxM+S0lsqY=
=xwcu
-----END PGP SIGNATURE-----

La signature semble correcte et nous pouvons vérifier tout cela avec :

$ gpg --verify amoi.tar.gz.asc amoi.tar.gz
gpg: Signature made mar 25 sep 2001 12:55:38 CEST using DSA key ID 47C5A6C8
gpg: Good signature from "Denis XXXXX <XXXXXXXXX@xxxxxxxxxxxx.org>"

Notre exemple concerne une archive tar compressée avec gzip. Dans le cas d'un fichier texte, il est possible d'intégrer la signature dans le fichier. Soit le fichier montexte.txt contenant ceci :

CECI EST UN FICHIER TEXTE :)

Il ne nous reste plus qu'à utiliser GnuPG pour y intégrer la signature électronique :

$ gpg --clearsign montexte.txt
You need a passphrase to unlock the secret key for
user: "Denis XXXXX <XXXXXXXXX@xxxxxxxxxxxx.org>"
1024-bit DSA key, ID 47C5A6C8, created 2000-05-14
Enter passphrase:

L'option --clearsign nous permet d'intégrer une signature dans le fichier. --clearsign, à l'inverse de --sign, permet de faire en sorte que cette signature soit ajoutée en ASCII. Avec --sign, nous obtiendrions un fichier binaire contenant message et signature. Nous obtenons ici un fichier montexte.txt.asc étant le nouveau fichier texte signé :

-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

CECI EST UN FICHIER TEXTE :)

-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.0.6 (GNU/Linux)
Comment: For info see http://www.gnupg.org

iD8DBQE7sGsTobIuzUPEs8gRAoucAJ9GSr0pi5ot0bR5OK29uYRe4yUx0wCfcVfy
qSw5klJD7VyWOPOcpudkc3o=
=uJV+
-----END PGP SIGNATURE-----

Nous voyons clairement les marqueurs insérés par GnuPG définissant le début du message signé, le début et la fin de la signature. Autre point intéressant, nous apprenons que le condensé de message utilise l'algorithme SHA1. Tout ce qui vous reste à faire est d'envoyer ce fichier (.asc) à tous ceux qui le souhaitent. Ils pourront facilement vérifier la signature intégrée avec :

$ gpg --verify montexte.txt.asc

En revanche, si le fichier venait à être modifié, par exemple en supprimant ou en ajoutant un caractère, GnuPG nous informerait immédiatement du problème :

$ gpg --verify montexte.txt.asc
gpg: Signature made mar 25 sep 2001 13:31:31 CEST using DSA key ID 47C5A6C8
gpg: BAD signature from "Denis XXXXX <XXXXXXXXX@xxxxxxxxxxxx.org>"


Le principe de confiance
En vérifiant la signature de l'archive patch du kernel 2.4.10, nous avons eu un message d'avertissement signalant un problème de confiance. Le Web of Trust repose sur le fait que les utilisateurs se connaissent les uns les autres et ne signent leurs clefs qu'après avoir vérifié les identités des intervenants. Malheureusement, il serait stupide de croire qu'il n'existe pas d'utilisateurs qui signent des clefs sans vérifier l'identité du détenteur.

Il ne s'agit pas forcément de malveillance ou de laxisme : une erreur est vite arrivée et personne n'est à l'abri d'une mauvaise manipulation.

Il faut donc disposer d'un moyen d'accorder plus ou moins confiance à certains utilisateurs. Voici un exemple : imaginons que le possesseur de la clef
77C8A6F8 soit connu pour signer à tout va les clefs des autres utilisateurs sans en vérifier l'identité. Nous ne pouvons pas faire confiance à cet individu en ce qui concerne les clefs qu'il signe ou qu'il a signé par le passé. Nous allons donc modifier son niveau de confiance :

$ gpg --edit-key 77C8A6F8
gpg (GnuPG) 1.0.6; Copyright (C) 2001 Free Software Foundation, Inc.
This program comes with ABSOLUTELY NO WARRANTY.
This is free software, and you are welcome to redistribute it
under certain conditions. See the file COPYING for details.

pub 1024D/77C8A6F8 created: 2001-08-12 expires: never trust: -/q
sub 1024g/4510B2G9 created: 2001-08-12 expires: never
(1). Denis Machin <kkun@ailleurs.org>
Command>

Nous allons utiliser la commande trust afin de modifier les paramètres de confiance qui ne sont pour l'instant pas définis (trust: -/q) :

Command> trust
Please decide how far you trust this user to correctly
verify other users' keys (by looking at passports,
checking fingerprints from different sources...)?

1 = Don't know
2 = I do NOT trust
3 = I trust marginally
4 = I trust fully
s = please show me more information
m = back to the main menu

Your decision?

Nous avons le choix entre plusieurs possibilités. Dans l'ordre :
1 - Nous ne pouvons porter aucun jugement sur cette personne.
2 - Cette personne est connue pour son laxisme et nous ne lui faisons pas confiance.
3 - Cette personne connaît le principe du Web of Trust et vérifie les identités avant de signer une clef.
4 - Cette personne maîtrise parfaitement le principe et ne signera jamais une clef sans vérifier avec la plus grande attention l'identité du détenteur de la clef.

Ici, la question ne se pose même pas, nous choisirons l'option
2 puisque c'était le but de la manipulation. Nous apercevons ensuite la mention "trust: n/q" qui indique notre nouveau niveau de confiance et le niveau de validité de la clef (q = aucun jugement). Une clef signée sera pleinement valide et nous pourrions par exemple avoir n/f, ce qui indiquerait que nous ne faisons pas confiance du tout à une personne dont la clef est pleinement valide car nous l'avons signée.

Les niveaux de confiance permettent de rendre une clef valide de manière plus souple qu'avec le mécanisme classique selon lequel une clef n'est valide que si vous-même l'avez signé (et donc vérifié l'identité du détenteur). Ce mécanisme plus souple permet de rendre valide une clef suivant ces conditions :

- La clef est signée par suffisamment de clefs valides. Cette condition peut être remplie de plusieurs manières :
         - Vous avez signé la clef en question.
         - La clef est signée par une personne dans laquelle vous avez pleinement confiance (
fully).
         - La clef est signée par un minimum de trois personnes dans lesquelles vous avez confiance (
marginally).

- La clef est signée par une personne dont la clef est signée par une personne... dont la clef est signée par vous-même. Il existe un chemin de signatures qui remonte jusqu'à une personne dont vous avez signé la clef en moins de 5 étapes/sauts.

Si ces conditions sont remplies, nous n'avons aucun message d'avertissement de la part de GnuPG.


Utilisation de GnuPG avec un client mail
Le mécanisme de signature électronique prend toute son ampleur lorsqu'il est mis en uvre dans le cadre d'une communication par courrier électronique. Il garantit ainsi la sécurité de toutes les communications. Un email corrompu, endommagé, modifié ou totalement contrefait sera immédiatement détecté et signalé.

Vérifier une signature électronique d'un mail est une chose facile puisque, en principe, il suffit d'appliquer exactement la même technique qu'avec un fichier de données. Le problème cependant est que ce genre de manipulation devient vite pénible lorsqu'on reçoit ou émet plus d'une vingtaine de messages par jour.

Heureusement pour nous, les clients mail (MUA) les plus courants (Mutt, Emacs/Gnus et Pine) possèdent des fonctionnalités permettant de les faire interagir de manière quasi transparente avec GnuPG. Comme nous l'avons dit plus haut, il existe deux méthodes pour signer un fichier texte (et donc un email) : la signature détachée et la signature dans le corps du texte.

La seconde méthode est de moins en moins utilisée et la signature détachée prend peu à peu le pas sur tout le reste. Dans ce cas, le message reste inchangé et la signature est envoyée en pièce jointe.

Un nouveau type Mime a été défini afin que les différents MUA puissent manipuler automatiquement la pièce jointe spécifique :
PGP/MIME. En fait, cette pièce n'est rien d'autre que le fichier de signature au format ASCII.

Si nous prenons le cas du MUA Mutt, la configuration est relativement aisée. Il vous suffira d'utiliser la version internationale de Mutt (dont le numéro de version est suffixé d'un
i). Avec une Debian, un apt-get install mutt sera suffisant pour installer la bonne version. En ce qui concerne la configuration à proprement parler, il est conseillé de placer les éléments de configuration dans un fichier séparé afin d'en faciliter la manipulation. Depuis votre fichier de configuration, vous n'aurez qu'à ajouter une ligne :

source ~/gpg.rc

Ce fichier est livré avec les sources de Mutt (dans le répertoire contrib) ; il vous suffira de le compiler dans votre répertoire personnel. Avec Mutt est également installé un petit script shell servant d'interface entre Mutt et GnuPG. Celui-ci, appelé pgpewrap, est utilisé par le fichier gpg.rc. Cette ligne intégrera les données du fichier gpg.rc (du répertoire personnel de l'utilisateur) dans la configuration de Mutt.

Dans le fichier de configuration, nous pourrons définir les éléments (variables) suivants :

set/unset pgp_autosig active ou désactive la signature automatique des messages envoyés.

set/unset pgp_autoencrypt, idem pour le chiffrement des messages.

set/unset pgp_encryptself permet de garder une version chiffrée des messages envoyés.

set/unset pgp_replysign permet d'activer automatiquement la signature d'un message s'il s'agit d'une réponse à un mail signé.

set/unset pgp_replyencrypt, idem pour le chiffrement du message.

set/unset pgp_verify_sig=yes est une option très intéressante : elle permet de vérifier automatiquement la signature des messages signés entrants. Mutt vous informera du résultat de la vérification dans la ligne d'état.

set/unset pgp_timeout=n permet de définir une durée en secondes (n) durant laquelle Mutt conservera la phrase de passe en mémoire. Ainsi, vous ne serez pas obligé de ressaisir celle-ci à chaque mail envoyé. Attention, ne fixez pas une durée trop longue, car en laissant votre poste sans surveillance avec la phrase de passe en mémoire, vous donnez l'occasion à n'importe qui d'envoyer des messages signés de votre main.

set/unset pgp_sign_as="0x--------" permet de spécifier l'ID d'une clef privée à utiliser pour signer vos messages. Cela s'avère très utile si vous avez plusieurs clefs secrètes dans votre trousseau.

set/unset pgp_long_ids active ou désactive l'utilisation d'ID 64 bits.

set/unset pgp_sign_micalg= permet de choisir l'algorithme de condensation à utiliser (pgp-sha1, pgp-md5 ou pgp-rmd160).

Viennent ensuite les éléments spécifiques à GnuPG :

set pgp_default_version=gpg pour le logiciel à utiliser ;
set pgp_key_version=default pour laisser le soin à GnuPG de choisir la clef par défaut ;
set pgp_receive_version=default, idem pour la réception de messages ;
set pgp_send_version=default et l'expédition ;
set pgp_gpg=/usr/local/bin/gpg pour spécifier le chemin vers le binaire ;
set pgp_gpg_pubring=~/.gnupg/pubring.gpg pour le fichier de clefs publiques ;
set pgp_gpg_secring=~/.gnupg/secring.gpg pour le fichier de clefs secrètes.

Avec ces quelques lignes dans vos fichiers de configuration, vous serez en mesure de recevoir et de vérifier automatiquement les signatures des messages au format
PGP/MIME. Un certain nombre de commandes vous permettront également de composer des messages signés ou chiffrés.

p activera le sous-menu PGP/GnuPG de Mutt ; vous pourrez utiliser ensuite l'une des commandes suivantes :
e pour chiffrer le message ;
s pour le signer ;
a pour le signer en choisissant une clef (dans le cas où vous en posséderiez plusieurs) ;
b pour signer et chiffrer le message ;
m pour choisir l'algorithme de condensation (hash) ;
f pour annuler les manipulations PGP/GnuPG.

En cas d'erreur dans la phrase de passe, vous pourrez utiliser la séquence
<CTRL>F afin de supprimer la phrase de la mémoire de Mutt.

Ces quelques indications devraient vous permettre de faire vos premiers pas dans l'utilisation de GnuPG et de commencer à correspondre de manière plus efficace et surtout plus sûre avec vos amis. Si votre MUA n'est pas Mutt, consultez les liens en fin d'article pour obtenir de la documentation sur la manière d'interfacer GnuPG avec votre client.

Liens
GnuPG
http://www.gnupg.org/

L'excellente documentation de Loic Bernable
http://www.vilya.org/gpg/gpg-intro.html

Le Howto Mutt/GnuPG/PGP
http://www.linuxdoc.org/HOWTO/Mutt-GnuPG-PGP-HOWTO.html

Le site du créateur de PGP/OpenPGP
http://web.mit.edu/~prz/

Le site Mutt en français
http://www.muttfr.org/

Emacs/Gnus en français
http://www.emacsfr.org//gen.php3/section/Mail,0,1,0.html

Utiliser Pine et GnuPG
http://www.linuxsecurity.com/feature_stories/feature_story-83.html