PGP (pour Pretty Good Privacy) est créé en 1991 par Phil Zimmermann. Militant antinucléaire depuis les années 80, il veut inciter les activistes à protéger leurs messages et leurs données. La licence est alors propriétaire mais l'utilisation non commerciale est gratuite et le code est fourni avec le logiciel. Après quelques années de développement rapide, de nombreux logiciels indépendants veulent s'interfacer avec PGP 5. Zimmermann décide en 1997 de créer le standard OpenPGP mais PGP est encore restreint aux États-Unis par la loi américaine d'export des logiciels de chiffrement. En réponse à un appel de Stallman la même année, Gnu Privacy Guard ou GnuPG est lancé en 1999 par Werner Koch afin de proposer une solution libre compatible. Son portage vers Windows sera assuré par le gouvernement allemand.
Il existe deux versions de GnuPG maintenues qui peuvent coexister. Nous utiliserons ici la version 2 mais elles sont parfaitement compatibles.
$ gpg --version gpg (GnuPG) 2.1.22 libgcrypt 1.8.0 Copyright (C) 2017 Free Software Foundation, Inc. License GPLv3+: GNU GPL version 3 or later <https://gnu.org/licenses/gpl.html> This is free software: you are free to change and redistribute it. There is NO WARRANTY, to the extent permitted by law
La syntaxe de GnuPG est parfois longue et il existe assez peu d'abréviations. Il est préférable d'avoir la complétion bash installée.
Introduction au chiffrement
Le chiffrement est un procédé qui permet de rendre inintelligibles des données à toute personne non autorisée. Seul le destinataire, possédant la clé, est en mesure de déchiffrer les données et donc d'y avoir accès. Il existe pour cela deux grandes méthodes de chiffrement : le chiffrement symétrique et le chiffrement asymétrique. La force des mots de passe utilisés sera le premier pilier de la fiabilité du chiffrement. Nous allons donc commencer par voir comment générer un mot de passe sûr.
Générer un mot de passe fort
$ gpg --armor --gen-random 1 20
L'option –armor permet de générer du format ASCII (par défaut, la sortie de gpg est au format binaire OpenPGP). Le premier chiffre (0, 1 ou 2) indique la qualité du mot de passe et le deuxième le nombre d'octets. Ici, on veut donc un mot de passe de 20 caractères de bonne qualité.
La génération de nombres aléatoires puise dans une réserve (pool), en général /dev/random, mais GnuPG implémente sa propre réserve. On considère qu'une suite de nombres imprévisibles peut être générée en combinant plusieurs sources de suites de nombres prévisibles. Sur Linux, cette réserve est remplie par la combinaison de sources simples comme le clavier, la souris, les accès au disque et certaines interruptions.
L'utilisation de ces réserves doit rester modérée afin de ne pas les épuiser, surtout si la qualité doit exceller (cf. Génération de nombres aléatoires pour plus de détails). Il est possible de consulter l'entropie disponible :
$ cat /proc/sys/kernel/random/entropy_avail 3758
Le chiffrement symétrique
Cette méthode consiste à utiliser une même clé secrète pour chiffrer et déchiffrer des données.
[caption id="attachment_4669" align="aligncenter" width="286"] Chiffrement symétrique[/caption]
GnuPG peut être utilisé pour chiffrer des données avec un mot de passe. Créons d'abord un fichier texte, puis chiffrons le :
$ echo "Coucou les gens" > ./data.txt $ gpg --armor --symmetric --cipher-algo AES256 --output ./data_enc.asc ./data.txt
Un mot de passe est demandé. Après l'avoir renseigné, le fichier chiffré data_enc.asc est créé :
$ cat data_enc.asc -----BEGIN PGP MESSAGE----- jA0EBwMCxs9Kfr3Y16HX0jwBMUYcz2zWPhsAlqLGxU9IuMcyUYaTC7Wan/JNilCY v8P3AyacaH7sITUA7yryKn7T0z7IXyBz2luvpHM= =3m/g -----END PGP MESSAGE-----
Ici, nous avons utilisé l'algorithme standard AES avec une taille de clé de 256 (AES256), d'autres algorithmes sont disponibles (AES192, AES256, TWOFISH, CAMELLIA128, CAMELLIA192, CAMELLIA256). La liste est accessible avec l'option –version.
Pour déchiffrer le message, il suffit de lancer la commande :
$ gpg --decrypt --output ./data_dec.txt ./data_enc.asc $ cat ./data_dec.txt Coucou les gens
Note : GnuPG démarre automatiquement l'agent gpg-agent qui garde votre mot de passe en cache. Si vous lancez le déchiffrement dans la même session, il est probable que votre mot de passe ne vous soit pas demandé. |
---|
Le chiffrement symétrique est une solution simple pour conserver des données confidentielles ou échanger des données rapidement, mais l'inconvénient est qu'il est nécessaire de partager le mot de passe de manière sécurisée avec le correspondant. Le chiffrement asymétrique permet de palier à cet inconvénient.
Le chiffrement asymétrique
Clé publique / clé privée
Contrairement au chiffrement symétrique, nous n'allons pas générer une clé seule mais une paire de clés : une clé publique et une clé privée. La première pourra être partagée alors que la deuxième devra rester secrète car c'est elle qui nous permettra de nous identifier, ou de déchiffrer des messages qui nous sont adressés. Lorsqu'un utilisateur a partagé sa clé publique, il est possible d'utiliser celle-ci pour chiffrer un message à sa destination. Seule la clé privée correspondante permet le déchiffrement.
Qu'est ce que la signature ?
La signature permet de certifier la provenance et l'intégrité d'un document. La clé secrète est utilisée pour apposer sa signature et la clé publique correspondante est utilisée pour la vérifier.
[caption id="attachment_4755" align="aligncenter" width="293"] A vérifie le fichier signé par B[/caption]
Qu'est ce qu'une identité OpenPGP ?
Une identité est la combinaison d'un nom et d'une adresse mail éventuellement accompagnés d'un commentaire. À chaque clé sont associées une ou plusieurs identités.
Qu'est ce qu'un réseau de confiance (WOT) ?
Afin de pouvoir utiliser une clé publique, il faut pouvoir authentifier l'identité de la clé, c'est-à-dire le lien qui unit une clé publique à son possesseur. En effet, aucune vérification d'identité n'est effectuée à la création des clés (voir ci-dessous), ce qui implique que n'importe qui peut se créer une identité OpenPGP avec votre nom. Afin q'une identité ne soit pas usurpée, il faut pouvoir authentifier le lien qui unit une clé à son propriétaire. Ce travail peut être délégué à une autorité de certification mais avec OpenPGP, on tisse généralement un réseau de confiance (WOT: Web Of Trust). Dans un WOT, une identité est jugée valide si elle a été certifiée par une clé de confiance forte ou bien par trois clés de confiance moyenne. Voici un article en anglais qui explique ce concept : https://www.linux.com/learn/pgp-web-trust-core-concepts-behind-trusted-communication. Pour certifier une identité PGP, on signe la clé publique d'une personne - après avoir vérifié son identité physiquement - avec notre propre clé privée.
Pour un usage plus avancé, on peut s'intéresser aux signatures de confiance : https://www.linux.com/blog/pgp-web-trust-delegated-trust-and-keyservers.
On pourrait aussi choisir de s'appuyer sur un algorithme d'après lequel la confiance est donnée à la première utilisation : Trust On First Use. Il est utilisé en ssh : l'empreinte de la cible doit être confirmée avant la première connexion.
On pourra à l'avenir mettre à jour et consulter son réseau de confiance (cette opération est souvent lancée automatiquement).
$ gpg --check-trustdb
[caption id="attachment_4759" align="aligncenter" width="257"] B certifie l'identité de A[/caption]
Partager sa clé publique: les serveurs de clés
Afin de partager notre clé publique, nous la publions sur un serveur de clés. Ces derniers permettent de répertorier les clés des utilisateurs et de faire le lien entre une clé publique et l'identité d'une personne. Parmi les serveurs de clés publiques on peut noter keys.gnupg.net et pgp.mit.edu. Si une paire de clés est compromise, ils permettent de déclarer une clé comme n'étant plus valide et d'interdire son utilisation.
Note: les clés enregistrées sur de tels serveurs y seront inscrites pour toujours. Attention donc à ne pas trop jouer avec ! |
---|
Qu'est-ce qu'une clé maîtresse et des sous-clés ?
Une clé maîtresse peut être associée à un nombre illimité de sous-clés. Ces sous-clés peuvent remplir les rôles de chiffrement ou de signature. C'est utile pour plusieurs raisons :
-
chiffrer ou signer sans exposer la clé privée maîtresse
-
répartir les rôles entre les clés
-
avoir des clés avec une date d'expiration raisonnable
-
avoir des clés facilement révocables
Ainsi, si une sous-clé est compromise, le périmètre impacté est restreint et la clé maîtresse reste viable.
Pratique : gestion d'un trousseau de clés OpenPGP
En tant qu'alternative à PGP, GnuPG a pour but de gérer des clés au standard OpenPGP. Avant toute chose, il va nous falloir créer notre propre paire de clés.
Génération d'une paire de clés
Pour générer une paire de clés avec quelques paramètres par défaut, nous pouvons utiliser la commande –gen-key qui va nous demander de créer une identité (le commentaire est facultatif) :
$ gpg --gen-key GnuPG doit construire une identité pour identifier la clé. Nom réel : Linux Embedded Adresse électronique : linux.embedded@mail.fr Commentaire : Vous avez sélectionné cette identité : « Linux Embedded <linux.embedded@mail.fr> » Changer le (N)om, le (C)ommentaire, l'(A)dresse électronique ou (O)ui/(Q)uitter ? o
Suivez les instructions, puis une fois la paire de clés générée, elle va être affichée (selon votre configuration, il est possible que certains paramètres soient fixés par défaut, auquel cas un message les indique avant votre clé).
pub rsa2048 2017-08-02 [SC] [expire : 2019-08-02] BBB9205AAD5DFC0718E484DED6C7070B1FA38BE4 BBB9205AAD5DFC0718E484DED6C7070B1FA38BE4 uid Linux Embedded <linux.embedded@mail.fr> sub rsa2048 2017-08-02 [E] [expire : 2019-08-02]
Pour plus de détails, on peut utiliser :
$ gpg --list-keys linux.embedded@mail.fr pub rsa2048 2017-08-02 [SC] [expire : 2019-08-02] BBB9205AAD5DFC0718E484DED6C7070B1FA38BE4 uid [ ultime ] Linux Embedded <linux.embedded@mail.fr> sub rsa2048 2017-08-02 [E] [expire : 2019-08-02]
On voit ici que deux paires de clés ont en fait été créées : une paire de clés dite maîtresse (pub rsa2048 2017-08-01 [SC]) et une paire de sous-clés (sub rsa2048 2017-08-01 [E]). Entre crochets, on peut voir le rôle de chacune des paires de clés. La paire de clés maîtresse peut signer (S = Signing) et certifier (C = Certification). La paire de sous-clés sert uniquement au chiffrement (E = Encryption). Dans le reste des informations, on trouve les dates de création et d'expiration, l'empreinte de la clé (BBB9205AA…) et la confiance accordée à l'identité (ultime).
Il existe six niveaux de confiance : inconnu, non décidé, aucune confiance, marginale, complète et ultime. Dans un WOT, on dit que la confiance dans l'identité est totale si elle est complète ou ultime, et partielle si elle est marginale.
Pour afficher les clés secrètes, on utilisera :
$ gpg --list-secret-keys linux.embedded@mail.fr sec rsa2048 2017-08-02 [SC] [expire : 2019-08-02] BBB9205AAD5DFC0718E484DED6C7070B1FA38BE4 uid [ ultime ] Linux Embedded <linux.embedded@mail.fr> ssb rsa2048 2017-08-02 [E] [expire : 2019-08-02]
Ces options sont assez flexibles : on peut renseigner un fragment du mail ou de l'identité, ou l'empreinte (ou rien pour afficher tout le trousseau).
Gestion des clés
Pour gérer une clé, nous allons ouvrir le menu d'édition dynamique :
$ gpg --edit-key <key>
La commande help liste les commandes disponibles. Les commandes les plus utiles sont les suivantes :
gpg> passwd # Change la phrase secrète gpg> clean # Nettoie les identités non utilisables et supprime les signatures inutilisables gpg> expire # Change la date d'expiration gpg> adduid # Ajoute une identité
Nous allons explorer les actions suivantes :
gpg> addkey # Ajoute une sous-clé gpg> sign # Signe une identité gpg> trust # Attribue un niveau de confiance gpg> revkey # Révoque une clé
Pour en sortir, selon si on veut sauvegarder ou non, on utilise save ou quit.
Créer une sous-clé
On a déjà une sous-clé pour le chiffrement, créons-en une pour la signature :
gpg> addkey
Choisissez une taille de clé, une date d'expiration (un an par exemple).
Échanger des clés
La clé privée doit rester secrète, mais la clé publique est faite pour être partagée. Pour cela, on l'exporte :
$ gpg --armor --export --output pubkey.asc linux.embedded@mail.fr
Cela crée un fichier ASCII qui peut être importé par notre correspondant :
$ gpg --import pubkey.asc
Exemple : importer cette clé. |
---|
Avant de valider l'identité de la personne, il faut vérifier que la clé reçue est la bonne (pour se prémunir d'un Man In The Middle). En général, on vérifie avec l'empreinte, la vérification la plus efficace étant de donner l'empreinte par oral (au téléphone).
$ gpg --fingerprint louis.rannou pub rsa4096 2015-11-12 [C] FA71 30F2 D329 4992 2F16 DD42 0064 DCFC 2131 0FEC uid [ inconnue] Louis Rannou <louis.rannou@gmail.com> uid [ inconnue] Louis Rannou <louis.rannou@protonmail.com> sub rsa4096 2015-11-12 [S] sub rsa4096 2015-11-12 [E]
Si l'identité est confirmée, nous pouvons la certifier dans le menu d'édition :
gpg> sign
Dans tous les cas, on peut lui attribuer une confiance. Si on est certain de l'identité, on lui attribuera une confiance complète. Si comme ici, la vérification n'est pas idéale, on lui attribue une confiance marginale :
gpg> trust Décidez maintenant de la confiance que vous portez en cet utilisateur pour vérifier les clés des autres utilisateurs (en regardant les passeports, en vérifiant les empreintes depuis diverses sources, etc.) 1 = je ne sais pas ou n'ai pas d'avis 2 = je ne fais PAS confiance 3 = je fais très légèrement confiance 4 = je fais entièrement confiance 5 = j'attribue une confiance ultime m = retour au menu principal Quelle est votre décision ? 3
Révocation de clés
En général on ne supprime pas une clé, on la révoque : on indique que cette clé ne doit plus être utilisée. Attention car toute révocation est irréversible !!!
Révoquer une sous-clé
Une sous-clé peut être révoquée grâce à sa clé maîtresse secrète. On utilise la commande dans le menu d'édition :
gpg> revkey
Révoquer une clé maîtresse
Si on veut révoquer la clé maîtresse, il faut générer un certificat de révocation. Il est intéressant de créer ce certificat dès la création car il permet de révoquer sa clé lorsqu'on n'en a plus le contrôle (mot de passe perdu, etc.).
$ gpg --gen-revoke linux.embedded@mail.fr --output revoke.asc
Attention, il faut garder secret ce certificat puisqu'il peut être utilisé par n'importe qui pour révoquer la clé. Pour ce faire, il suffit d'importer le certificat :
$ gpg --import revoke.asc
Supprimer une clé
Il est possible de supprimer des clés publiques, secrètes ou les deux :
$ gpg --delete-keys louis.rannou $ gpg --delete-secret-keys $ gpg --delete-secret-and-public-keys
Sauvegarder ses clés
Avant d'aller plus loin, il nous faut recréer une clé. On peut régler plus de paramètres avec la commande –full-gen-key (et si on veut, on peut même y rajouter l'option –expert) :
$ gpg --full-gen-key
Pour sauvegarder la clé secrète, on l'exporte. Il est préférable de chiffrer cette sauvegarde avec un mot de passe fort :
$ gpg --armor --export-secret-keys linux.embedded@mail.fr | gpg --armor --symmetric --output sec.asc
Pour restaurer la clé, on l'importe :
$ gpg --import
On peut aussi sauvegarder les sous-clés :
$ gpg --armor --export-secret-subkeys linux.embedded@mail.fr
Partager une clé sur un keyserver
Note: les clés enregistrées sur de tels serveurs y seront inscrites pour toujours. Attention donc à ne pas trop jouer avec ! |
---|
Plutôt que d'échanger les clés à la main, on enregistre généralement sa clé sur un serveur de clés. Par défaut gpg utilise les serveurs indiqués dans ~/.gnupg/gpg.conf. On peut aussi le spécifier dans la ligne de commande :
$ gpg --keyserver keys.gnupg.net --send-keys linux.embedded@mail.fr
On utilise principalement hkp://keys.gnupg.net et hkp://pgp.mit.edu. Cela a peu d'importance car les différents serveurs se partagent généralement les informations.
Pour rechercher une clé, on pourra utiliser la commande :
$ gpg --search-key <name>
Ou plus directement :
$ gpg --recv-keys <fingerprint>
Utilisation des clés
Chiffrement asymétrique
Nous pouvons maintenant utiliser la clé publique créée pour chiffrer un fichier qui ne sera déchiffrable qu'avec la clé secrète associée :
gpg --armor --recipient "Linux Embedded" --output data_enc.asc --encrypt data.txt gpg --output data_dec.txt --decrypt data_enc.asc
Ici, nous chiffrons un message pour “Linux Embedded”, mais on peut ajouter un nombre indéfini de destinataires (option –recipient). Il est aussi possible de le combiner au chiffrement symétrique :
gpg --armor --recipient "Linux Embedded" --output data_enc.asc --symmetric --encrypt data.txt
Signer un document
Pour créer un fichier signé, nous utilisons la commande –sign ou –clearsign si on veut qu'il reste dans un format humainement lisible. Pour vérifier la signature, on le déchiffre :
$ gpg --output ./data.sig --sign ./data.txt $ gpg --output ./data.sig --clearsign ./data.txt $ gpg --decrypt ./data.sig
Le fichier créé contient alors à la fois le fichier source et la signature. Il est possible d'avoir une signature détachée que l'on peut vérifier avec la commande –verify :
$ gpg --output ./data.sig --detach-sign ./data.txt $ gpg --verify ./data.sig
Applications courantes
Messagerie
Pour thunderbird, enigmail est un plugin qui permet de chiffer/déchiffrer signer/vérifier un message. Certains fournisseurs de mail comme protonmail utilisent des clés OpenPGP nativement.
Git
Avec Git, on peut signer les commits et les tags en ajoutant une clé à l'utilisateur :
$ git config --global user.signingkey BBB9205AAD5DFC0718E484DED6C7070B1FA38BE4
La signature d'un tag est utile en développement pour savoir qui certifie la stabilité de la version.
Authentification de paquets
Gérer ses mots de passe avec PasswordStore pour Linux
Password Store est un programme qui permet la sauvegarde de mots de passe à l'aide de clés gpg et la synchronisation sur un serveur git. Son utilisation est très accessible et parfaitement détaillée sur son site et sur sa page man.
Voici quelques commandes utiles pour démarrer. On commence par initialiser un “magasin de mots de passe” :
$ pass init <identité gpg>
où l'identité gpg peut être le nom, ici “Linux Embeded”, ou l'adresse e-mail, ici linux.embedded@mail.fr, utilisé lors de la création de la paire de clé. On vient ici de créer le répertoire ${HOME}/.password-store Si vous souhaitez utiliser git pour synchroniser vos mots de passe entre vos différents appareils :
$ pass git init
Ceci va initialiser le répertoire ${HOME}/.password-store pour utiliser git. On ajoute ensuite le serveur distant :
$ pass git remote add origin login@server:/path/to/password-store
Note: Il peut s'agir d'un dépôt git public car les mots de passe sont stockés chiffrés avec votre clé secrète |
---|
On peut ensuite ajouter un mot de passe :
$ pass insert Email/email_provider
Un mot de passe vous sera alors demandé. On vient ici de créer le fichier <Email/email_provider.pgp> dans le répertoire ${HOME}/.password-store/. On remarque qu'on peut donc facilement organiser nos mots de passe en arborescence et ajouter un mot de passe pour une deuxième boite mail :
$ pass insert Email/email_provider2
Vous pouvez rentrer le mot de passe de votre choix, mais c'est peut-être l'occasion de changer vos mots de passe afin d'en utiliser des forts en les générant avec gpg. On peut même utiliser directement :
$ pass generate Email/email_provider2 20
Chaque opération sur les mots de passe (ajout/suppression/modification) sera sauvegardée par un commit. Il faudra donc régulièrement pousser les modifications sur le serveur pour pouvoir rester synchronisé entre les différents appareils :
$ pass git push
On peut ensuite lister ses mots de passe avec la commande pass :
$ pass Password Store └── Email ├── email_provider2 └── email_provider
Pour utiliser un mot de passe, on peut l'afficher :
$ pass Email/email_provider 'toC4CK^1"DM/_we^+$+S
Et pour le copier directement dans le presse papier :
$ pass -c Email/email_provider Copied Email/email_provider to clipboard. Will clear in 45 seconds.
Pour supprimer un mot de passe :
$ pass rm Email/email_provider2
Voici une liste de clients compatibles. Certains comme qtpass proposent une interface graphique, qui permet de simplifier la gestion de ses mots de passe.
OpenKeyChain : gérer ses clés OpenPGP sur Android
OpenKeyChain est un gestionnaire de clés pour Android. On peut ainsi exporter notre trousseau de clés vers un appareil Android. OpenKeyChain est compatible avec K9 mail pour chiffrer les mails, Conversation pour chiffrer les messages et… Password Store sur Android pour nos mots de passe!
Les quatre applications sont disponibles sur F-Droid :
Configuration d'OpenKeyChain
Exporter son trousseau de clés vers OpenKeyChain :
$ génération d'un mot de passe fort pour chiffrer la sauvegarde gpg --armor --gen-random 1 20 $ utilisation du mot de passe précédent pour exporter le trousseau gpg --armor --export-secret-keys <linux.embedded@mail.fr> | gpg --armor --symmetric --output mykey.sec.asc
Il faut ensuite transférer le fichier mykey.sec.asc sur la carte SD de votre appareil Android. Dans OpenKeyChain, ouvrir le menu et cliquer sur “Sauvegarder/Restaurer”, puis dans la section “Restaurer”, ouvrir le fichier de sauvegarde. Le mot de passe précédent vous est alors demandé.
Note: vous pouvez transférer le fichier de sauvegarde par email si vous n'avez pas accès à la carte SD de votre appareil à condition d'utiliser un mot de passe fort. Et surtout, évitez les générateurs de mot de passe en ligne |
---|
Une fois OpenKeyChain configuré, on peut installer et configurer les K9Mail, Conversation et Password Store.
Pour aller plus loin
GPG agent
gpg-agent permet de garder en cache un mot de passe. C'est utile si gpg est appelé par un programme ou un script.
SSH
Il est possible d'utiliser des sous-clés pour l’authentification, notamment par ssh.
Génération de nombres pseudo-aléatoires
On peut consulter à ce propos les pages wikipédia (en anglais de préférence) CSPRNG, PRNG, /dev/random et éventuellement la preuve de la génération d'une source imprévisible.
Voici une page sur la gestion de l'entropie sur Linux.
Enfin, un lien pour comprendre pourquoi la génération de nombres aléatoires nuit à l'entropie de votre système.
Petit aparté sur les mots de passe
Appendice
Abréviations GnuPG utiles
-
-a : –armor
-
-k : –list-keys
-
-K : –list-secret-keys
-
-c : –symmetric
-
-d : –decrypt
-
-o : –output
-
-e : –encrypt
-
-r : –recipient
-
-s : –sign
-
-b : –detach-sign
Sources
-
GNU/Linux Magazine n°168