GPG/PGP
OpenPGP
: pourquoi mais aussi et surtout, comment. Alice et Bob à la rescousse pour comprendre comment communiquer de manière chiffrée en utilisant cette technologie. Les exemples en complexité croissante présentés dans cette page permettent d’appréhender les tenants et aboutissants d’OpenPGP
.
GnuPG
ou GPG
est une implémentation open-source du standard OpenPGP
datant de 1997, lui-même élaboré à partir de PGP
développé en 1991.
Il s’agit d’un système de chiffrement asymétrique (clé privée / clé publique). Le principe est simple : une clé publique permet de chiffrer des données que seule la clé privée associée permet de déchiffrer.
Les utilisateurs de Protonmail
utilisent GPG
en permanence sans y faire attention car non seulement de la génération des clés est prise en charge mais aussi le (dé)chiffrement des échanges entre les utilisateurs. Ce guide a pour but de détailler toutes ces étapes cachées afin de comprendre ce qui se passe en pratique mais aussi de montrer comment aller plus loin avec GPG
et notamment son usage pour accéder à des machines distantes via SSH
.
Génération d’un trousseau GPG
Il existe deux niveaux d’usage de GPG
: normal et expert. Dans un premier temps sera présenté comment générer un trousseau de clés GPG
en quelques lignes, en mode normal. Le mode expert sera ensuite utilisé pour créer un second trousseau avec des options plus poussées. Puis ces deux trousseaux seront utilisés pour effectuer un échange chiffré de l’un à l’autre et inversement.
La méthode simple
La méthode la plus simple ne demande que quelques secondes et ne configure rien d’autre qu’un nom d’utilisateur et une phrase de passe :
$ gpg --quick-generate-key Alice
# About to create a key for:
# "Alice"
#
# Continue? (Y/n) y
# We need to generate a lot of random bytes. It is a good idea to perform
# some other action (type on the keyboard, move the mouse, utilize the
# disks) during the prime generation; this gives the random number
# generator a better chance to gain enough entropy.
# We need to generate a lot of random bytes. It is a good idea to perform
# some other action (type on the keyboard, move the mouse, utilize the
# disks) during the prime generation; this gives the random number
# generator a better chance to gain enough entropy.
# gpg: $HOME/.gnupg/trustdb.gpg: trustdb created
# gpg: key 3DCB3624028F6F55 marked as ultimately trusted
# gpg: directory '$HOME/.gnupg/openpgp-revocs.d' created
# gpg: revocation certificate stored as '$HOME/.gnupg/openpgp-revocs.d/1F12D0A6ED98EE8556F3B4C93DCB3624028F6F55.rev'
# public and secret key created and signed.
#
# pub rsa3072 2021-01-30 [SC] [expires: 2023-01-30]
# 1F12D0A6ED98EE8556F3B4C93DCB3624028F6F55
# uid Alice
# sub rsa3072 2021-01-30 [E]
La génération rapide d’un trousseau pour Alice donne plusieurs choses :
- Un trousseau au nom de Alice composé de deux clés :
- Une clé publique principale pub au format RSA 3072 bits avec les flags
[SC]
pour sign et certify. Cette clé se voit attribuer une date d’expiration d’ici à deux ans. Nous verrons à quoi servent les flagsS
etC
ainsi que comment supprimer ou mettre à jour cette date plus loin dans ce guide. - Une sous-clé publique sub, elle aussi au format RSA 3072 bits avec le flag
[E]
pour encryption. Cette sous-clé n’a pas de date de validité.
- Une clé publique principale pub au format RSA 3072 bits avec les flags
- Un certificat de révocation propre à ce trousseau. L’usage des certificats de révocation sera lui aussi détaillé plus loin dans ce guide.
Le flag E
(encryption) quant à lui, désigne une clé dédiée au chiffrement des données à destination d’Alice. C’est cette clé que Alice devra partager avec le monde si elle souhaite que d’autres personnes puissent lui adresser des messages chiffrés.
Il est possible de voir les clés et sous-clés privées correspondantes :
$ gpg --list-secret-keys
# gpg: checking the trustdb
# gpg: marginals needed: 3 completes needed: 1 trust model: pgp
# gpg: depth: 0 valid: 2 signed: 0 trust: 0-, 0q, 0n, 0m, 0f, 2u
# gpg: next trustdb check due at 2023-01-30
# $HOME/.gnupg/pubring.kbx
# -------------------------------
# sec rsa3072 2021-01-30 [SC] [expires: 2023-01-30]
# 1F12D0A6ED98EE8556F3B4C93DCB3624028F6F55
# uid [ultimate] Alice
# ssb rsa3072 2021-01-30 [E]
La méthode avancée
Cette seconde méthode est à l’opposée de la première : elle utilise le mode expert et permet de choisir en détail de nombreuses options. Elle n’est pas forcément meilleure, mais il est toujours intéressant d’avoir un aperçu des possibles.
$ gpg --full-generate-key --expert
# gpg (GnuPG) 2.2.27; Copyright (C) 2021 Free Software Foundation, Inc.
# This is free software: you are free to change and redistribute it.
# There is NO WARRANTY, to the extent permitted by law.
#
# Please select what kind of key you want:
# (1) RSA and RSA (default)
# (2) DSA and Elgamal
# (3) DSA (sign only)
# (4) RSA (sign only)
# (7) DSA (set your own capabilities)
# (8) RSA (set your own capabilities)
# (9) ECC and ECC
# (10) ECC (sign only)
# (11) ECC (set your own capabilities)
# (13) Existing key
# (14) Existing key from card
Your selection? 11
#
# Possible actions for a ECDSA/EdDSA key: Sign Certify Authenticate
# Current allowed actions: Sign Certify
#
# (S) Toggle the sign capability
# (A) Toggle the authenticate capability
# (Q) Finished
#
Your selection? s
#
# Possible actions for a ECDSA/EdDSA key: Sign Certify Authenticate
# Current allowed actions: Certify
#
# (S) Toggle the sign capability
# (A) Toggle the authenticate capability
# (Q) Finished
#
Your selection? q
# Please select which elliptic curve you want:
# (1) Curve 25519
# (3) NIST P-256
# (4) NIST P-384
# (5) NIST P-521
# (6) Brainpool P-256
# (7) Brainpool P-384
# (8) Brainpool P-512
# (9) secp256k1
Your selection? 1
# Please specify how long the key should be valid.
# 0 = key does not expire
# <n> = key expires in n days
# <n>w = key expires in n weeks
# <n>m = key expires in n months
# <n>y = key expires in n years
Key is valid for? (0)
Key does not expire at all
Is this correct? (y/N) y
# GnuPG needs to construct a user ID to identify your key.
#
# Real name: Bob
# Email address:
# Comment:
# You selected this USER-ID:
# "Bob"
#
Change (N)ame, (C)omment, (E)mail or (O)kay/(Q)uit? o
# We need to generate a lot of random bytes. It is a good idea to perform
# some other action (type on the keyboard, move the mouse, utilize the
# disks) during the prime generation; this gives the random number
# generator a better chance to gain enough entropy.
# gpg: key DE9A4020694CF411 marked as ultimately trusted
# gpg: revocation certificate stored as '$HOME/.gnupg/openpgp-revocs.d/275BBDB1867217C5151D9747DE9A4020694CF411.rev'
# public and secret key created and signed.
#
# pub ed25519 2021-01-30 [C]
# 275BBDB1867217C5151D9747DE9A4020694CF411
# uid Bob
Les étapes sont les suivantes :
- Sélection d’un algorithme cryptographique. La méthode rapide utilise le RSA 3072 bits, mais il y a de nombreuses autres possibilités. Le choix
(11) ECC (set your own capabilities)
correspond à la cryptographie basée sur les courbes elliptiques (ECC) qui est actuellement considérée comme à la fois plus sûre et plus rapide que les algorithmes RSA même avec des clés plus courtes. - Sélection des flags pour cette clé principale. Le flag
C
(certify) est obligatoire pour la clé principale (et interdit pour les clés secondaires, l’explication plus loin dans ce guide). En entrants
suivi deentrée
, le flagS
Sign est désactivé. Entrerq
suivi deentrée
valide la sélection : une clé uniquement dotée du flagC
. - Sélection du type de courbe. En effet, il existe de multiples courbes utilisables pour la cryptographie sur courbes elliptiques. Le choix
(1) Curve 25519
correspond à l’une des plus sûres et rapides en ce moment. - Sélection de la durée de validité de la clé principale. Ici,
0
, la valeur par défaut, indique que la clé principale n’expirera jamais. C’est généralement le choix conseillé s’il est sûr qu’elle sera conservée en sécurité. GPG
demande ensuite le nom du propriétaire ainsi que son adresse email, facultative, et un commentaire, tout aussi facultatif. Biee que ce ne soit pas détaillé dans ce guide, il est possible d’attribuer plusieurs identités (UID) à un trousseauGPG
. Il peut donc être intéressant d’avoir Bob bob@mail.pro (Pro) et Bob bob@mail.perso (Perso).
Contrairement à la méthode simple, une seule clé est générée avec le flag C
. On retrouve par contre bien le certificat de révocation propre à ce trousseau.
Pour pouvoir utiliser ce trousseau pour du chiffrement, il est nécessaire de générer une sous-clé dédiée avec (au moins) le flag E
. À cette fin, il est possible d’éditer la clé nouvellement créee :
$ gpg --edit-key --expert Bob
# gpg (GnuPG) 2.2.27; Copyright (C) 2021 Free Software Foundation, Inc.
# This is free software: you are free to change and redistribute it.
# There is NO WARRANTY, to the extent permitted by law.
#
# Secret key is available.
#
# sec ed25519/DE9A4020694CF411
# created: 2021-01-30 expires: never usage: C
# trust: ultimate validity: ultimate
# [ultimate] (1). Bob
gpg> addkey
# Please select what kind of key you want:
# (3) DSA (sign only)
# (4) RSA (sign only)
# (5) Elgamal (encrypt only)
# (6) RSA (encrypt only)
# (7) DSA (set your own capabilities)
# (8) RSA (set your own capabilities)
# (10) ECC (sign only)
# (11) ECC (set your own capabilities)
# (12) ECC (encrypt only)
# (13) Existing key
# (14) Existing key from card
Your selection? 12
# Please select which elliptic curve you want:
# (1) Curve 25519
# (3) NIST P-256
# (4) NIST P-384
# (5) NIST P-521
# (6) Brainpool P-256
# (7) Brainpool P-384
# (8) Brainpool P-512
# (9) secp256k1
Your selection? 7
# Please specify how long the key should be valid.
# 0 = key does not expire
# <n> = key expires in n days
# <n>w = key expires in n weeks
# <n>m = key expires in n months
# <n>y = key expires in n years
Key is valid for? (0) 6m
Key expires at Thu 29 Jul 2021 10:30:04 AM CEST
Is this correct? (y/N) y
Really create? (y/N) y
# We need to generate a lot of random bytes. It is a good idea to perform
# some other action (type on the keyboard, move the mouse, utilize the
# disks) during the prime generation; this gives the random number
# generator a better chance to gain enough entropy.
#
# sec ed25519/DE9A4020694CF411
# created: 2021-01-30 expires: never usage: C
# trust: ultimate validity: ultimate
# ssb brainpoolP384r1/412650A16DB5F3C8
# created: 2021-01-30 expires: 2021-07-29 usage: E
# [ultimate] (1). Bob
#
gpg> save
Les étapes sont les suivantes :
- La commande
addkey
déclenche l’ajout d’une sous-clé pour le trousseau de Bob. - Le choix
(12) ECC (encrypt only)
permet de choisir de nouveau la cryptographie sur courbes elliptiques avec uniquement le flagE
activé. - L’usage du type de courbe
(7) Brainpool P-384
au lieu de(1) Curve 25519
sera expliqué plus tard dans ce guide. - La durée de validité de cette sous-clé dédiée au chiffrement est réglée à six mois. Il est possible, grâce à la clé principale, de changer la durée de validité d’une sous-clé. Il est généralement conseillé de fixer une date d’expiration aux sous-clés afin qu’elles soient automatiquement rendues inutilisable en cas de perte ou de vol.
- La commande
save
sauvegarde les modifications apportées au trousseau de Bob et quitteGPG
.
À ce moment du guide, Alice possède une clé principale capable de signer et certifier ainsi qu’une clé secondaire ou sous-clé capable de (dé)chiffrer Bob, quant à lui, possède une clé principale capable uniquement de certifier et une sous-clé capable de (dé)chiffrer.
$ gpg --list-key Alice
# pub rsa3072 2021-01-30 [SC] [expires: 2023-01-30]
# 1F12D0A6ED98EE8556F3B4C93DCB3624028F6F55
# uid [ultimate] Alice
# sub rsa3072 2021-01-30 [E]
$ gpg --list-key Bob
# pub ed25519 2021-01-30 [C]
# 275BBDB1867217C5151D9747DE9A4020694CF411
# uid [ultimate] Bob
# sub brainpoolP384r1 2021-01-30 [E] [expires: 2021-07-29]
Partage des clés publiques
Afin que Alice envoie des messages chiffrés à Bob, il faut auparavant qu’elle ait connaissance de la clé publique de chiffrement (flag E
) de ce dernier. Il existe deux façons de partager une clé publique avec une autre personne: en la transmettant directement ou en l’envoyant sur un serveur de clés publiques.
Envoyer directement sa clé publique
Bob veut pouvoir être contacté par Alice, il faut donc qu’il lui transmette sa clé publique de chiffrement :
$ gpg --export Bob
# 3`H +G@vJvUϳCg_
# &8;OBo8!%7dWRY9`H
#
#
# l29ST6w`Ig +$ W
# fgHIӞm=>nY9z̩} ge;>I=J
# Ǘ"Yo.Rd¨]"Cmtz8&!%7dWRY9`Ig$=q|aeAզ)Ve6CH+
#
# s`O +$Y9Ar]"H5Kڞ:$#X!jBxg;p>|h"lg
# q#r߆`^tȖ#Ue\E%CT#.9;%<v7v*@@)cPV9A%Vn
# &!%7dWRY9`O WRY9 !V_\46S7?`O
# ?4n-LErbDTpb}/<g1m$,ۅep$}r5yA h.gkuOLw؝JdY29LAlyUZe^"ґׯ [dsD738^zp1DHMOwя.
Par défaut, GPG
exporte les clés au format binaire. Cela peut être idéal pour la transmission à un serveur de clés, mais ce n’est pas viable pour un échange direct à un autre personne. Heureusement, GPG
propose un format Armure ASCII, plus pratique dans le cas présent :
$ gpg --export --armor Bob
# -----BEGIN PGP PUBLIC KEY BLOCK-----
#
# mDMEYBRI5RYJKwYBBAHaRw8BAQdA6AfMdkq3xex2Vc+zkkPZGIr7ZwZf3+UMhSaR
# ONA7T/O0A0JvYoiQBBMWCAA4FiEE6Q/u5ICc/iU3raxkV51Sp1kD9zkFAmAUSOUC
# GwEFCwkIBwIGFQoJCAsCBBYCAwECHgECF4AACgkQV51Sp1kD9zmVgAEAtYMxCMka
# g3rMqX0NZrehZ7H00ZCX40hJnNOebeg9gekA/j7qum4JZ7IoQBlJRD3MShwbTdNX
# 75QNnWwyOVPGVDYFuHcEYBRJZxIJKyQDAwIIAQELAwMEZeA7PkkJEQwpzhMtYR22
# JNc9f5hxGLWdFLh8u2FliEH71abMKatWsOplyjbWQ0iLBysNiKI+KmXGGX99qQ3H
# lyJZ1m+Slq0u3lLO0WTCqB2HtV30IkPnx6ptdHrjOLitAwEJCIh+BBgWCAAmFiEE
# 6Q/u5ICc/iU3raxkV51Sp1kD9zkFAmAUSWcCGwwFCQDtTgAACgkQV51Sp1kD9znM
# QQEA45tyhcXQXSK4l49INd9LpP7anvcFOiQjWNfAIRFqsIcBAK1CvHj/ZxUT8vI7
# cPc+fKQFtoVou9EZmCKKFIZsZ/cNuHMEYBRPBhMJKyQDAwIIAQELAwMEcfL0qyNy
# 34brwmDxsl50/ZPIliPe6hvzWdpVZZC+XEWMBOwlsusBy0PrVBLX5yOFLjk7JRIu
# nggWzP08djd2Aq+qKpdA5NSXQClj8LlQ14oH9VY5QaQlVtVujQWCDIAXiQEVBBgW
# CAAmFiEE6Q/u5ICc/iU3raxkV51Sp1kD9zkFAmAUTwYCGwIFCQDtTgAAoQkQV51S
# p1kD9zmWIAQZEwkAHRYhBFZfXDQ2w1M3mPcPz/8dP/8V8NLLBQJgFE8GAAoJEP8d
# P/8V8NLLf54BgII0br3ELUxFcn/dYtlEA+/2gFTBcGIEk30vktXa+4w8BGcxbfYk
# LIDbhQBl3HDuJAF9HMMacpcHtDWheRNBnSCgqx4E2GgFLqvM0u3bZ5sGa3VPHUx3
# 2J1KE7pkWTI5TEHR7bMBAMpseeZVg1oHZV6WIqAY0pHXr5ogWwTpi2TTc0T8NxXA
# AQCUMzhe73pw9fYxRLzc45YfSMGsTU8R+nfRj/q2LrHVBQ==
# =rMwf
# -----END PGP PUBLIC KEY BLOCK-----
Bob peut envoyer cette version à Alice par n’importe quel moyen, il s’agit de sa clé publique qui peut être lue sans crainte par tout le monde.
Alice quant à elle doit importer cette clé grâce à la commande gpg --import
. Elle disposera alors dans son trousseau de ses propres clés publiques et privées ainsi que de la clé (publique uniquement) de Bob.
Pousser sa clé sur un (ou plusieurs) serveurs de clés
Si Bob souhaite partager sa clé publique à plus d’une personne, il est plus simple de la rendre accessible via un serveur de clés. Cela à un autre avantage non négligeable : le jour où Bob change (généralement allonge) la durée de validité de sa clé publique et la pousse à nouveau sur le serveur de clés, les personnes qui souhaitent lui écrire peuvent récupérer la version à jour (ou une nouvelle clé publique si jamais Bob en a généré une nouvelle).
Pousser les clés utilisées dans ce guide n’aurait pas de sens mais les commandes suivantes seraient utilisées :
Sur la machine de Bob
gpg --send-keys
Sur la machine de Alice
gpg --search-keys Bob
Il existe de nombreux serveurs de clés différents qui peuvent être renseignés dans la configuration de GPG
(non traitée dans ce guide). De plus, la plupart de ces serveurs sont fédérés, c’est-à-dire qu’ils échangent régulièrement les informations sur leur contenu afin d’assurer une plus grande disponibilité des clés publiques les plus récentes possible.
La suite de ce guide suppose que Alice a partagé sa clé avec Bob et inversement, peu importe la méthode choisie.
Échange chiffré
Lorsque l’on utilise un système de chiffrement asymétrique, il est capital de vérifier si la clé publique appartient bien au destinataire de notre message. GPG
implémente un système poussé (non détaillé dans ce guide) appelé Web of Trust permettant un transfert de confiance pour vérifier les identités.
Pour la suite de ce guide, il est nécessaire pour Alice de signifier qu’elle sait que la clé qu’elle a reçue appartient bien à Bob et inversement. C’est à cela que servent les clés dotées du flag C
: elles permettent de certifier que le propriétaire de la clé publique est bien celui qu’il prétend être. C’est aussi pour cela que seule la clé principale peut être dotée du flag C
: c’est celle qui doit être à tout prix protégée car elle permet (entre autre) de donner publiquement la confiance du propriétaire aux clés des autres utilisateurs de GPG
.
Sur la machine d’Alice
$ gpg --edit-key Bob
# gpg (GnuPG) 2.2.27; Copyright (C) 2021 Free Software Foundation, Inc.
# This is free software: you are free to change and redistribute it.
# There is NO WARRANTY, to the extent permitted by law.
#
# Secret key is available.
#
# sec ed25519/DE9A4020694CF411
# created: 2021-01-30 expires: never usage: C
# trust: ultimate validity: ultimate
# ssb brainpoolP384r1/412650A16DB5F3C8
# created: 2021-01-30 expires: 2021-07-29 usage: E
# [ultimate] (1). Bob
gpg> lsign
# sec ed25519/DE9A4020694CF411
# created: 2021-01-30 expires: never usage: C
# trust: ultimate validity: ultimate
# Primary key fingerprint: 275B BDB1 8672 17C5 151D 9747 DE9A 4020 694C F411
#
# Bob
#
# Are you sure that you want to sign this key with your
# key "Alice" (3DCB3624028F6F55)
#
# The signature will be marked as non-exportable.
Really sign? (y/N) y
gpg> save
Sur la machine de Bob
$ gpg --edit-key Alice
# gpg (GnuPG) 2.2.27; Copyright (C) 2021 Free Software Foundation, Inc.
# This is free software: you are free to change and redistribute it.
# There is NO WARRANTY, to the extent permitted by law.
#
# Secret key is available.
#
# sec rsa3072/3DCB3624028F6F55
# created: 2021-01-30 expires: 2023-01-30 usage: SC
# trust: ultimate validity: ultimate
# ssb rsa3072/22D16254C17F81BD
# created: 2021-01-30 expires: never usage: E
# [ultimate] (1). Alice
gpg> lsign
# sec rsa3072/3DCB3624028F6F55
# created: 2021-01-30 expires: 2023-01-30 usage: SC
# trust: ultimate validity: ultimate
# Primary key fingerprint: 1F12 D0A6 ED98 EE85 56F3 B4C9 3DCB 3624 028F 6F55
#
# Alice
#
# This key is due to expire on 2023-01-30.
# Are you sure that you want to sign this key with your
# key "Bob" (DE9A4020694CF411)
#
# The signature will be marked as non-exportable.
#
Really sign? (y/N) y
gpg> save
Une méthode plus courte mais moins nuancée serait gpg --sign-key Bob
depuis la machine d’Alice. Cependant cette approche donne en réalité plus de confiance que lsign
(local sign) : la confiance attribuée par la méthode courte peut être partagée via les serveurs de clés alors que lsign
ne concerne que la machine sur laquelle la signature a lieu.
L’envoi
Alice souhaite communiquer un message de la plus haute importance à Bob : son animal favori !
$ echo Autruche | gpg --encrypt --recipient Bob
# gpg: checking the trustdb
# gpg: marginals needed: 3 completes needed: 1 trust model: pgp
# gpg: depth: 0 valid: 2 signed: 0 trust: 0-, 0q, 0n, 0m, 0f, 2u
# gpg: next trustdb check due at 2023-01-30
# A&Pm9j>oMȮͣ&O!-w[
# j-Wq cj+vc^mJ7J 3z)ʗ#U$x-0 06qUd@<H{1M<4UghDG6Gz$AX˭)4.H0-s$aѣVa[5m=Qf+
# :
Là encore, GPG
préfère le format binaire. Une version Armure ASCII peut être plus pratique dans certains cas :
$ echo Autruche | gpg --encrypt --armor --recipient Bob
# -----BEGIN PGP MESSAGE-----
#
# hJ4DQSZQoW2188gSAwMEKMIaehckBbKidJ0BJKpkloyCk5jrWMLDQgbrRk8wmhW/
# kzhWsNt4KZC2E6MeGRdOdRcV2HaB4dTFrVh234XdKpqJPLq8CXvsXU9Hg63jzmZT
# 0inAMogc9l4gKo6hX4s/MD3VswuqRjO9wT1J8WAB7pmgqcfNxN089GCfaA2QPzsL
# ZbI4ppmF1kjmYS9aMK2dsdJEAbFhaW/syzyYkyfRvLeiebqBDFHpv+dgArLcmfx/
# OKtMP3C7ymFcmYsoBOmNPIyE4T+jZtPrmpT8JmM4izXwM+PrtzI=
# =TWdE
# -----END PGP MESSAGE-----
À ce moment, Alice peut faire passer ce message chiffré par n’importe quel moyen, sécurisé ou non, personne d’autre que Bob ne peut le déchiffrer. Et pour cause, seul Bob dispose de la clé privée associée à la clé publique qui a servi à chiffrer le message par Alice.
Dans le cas présent, même Alice ne peut déchiffrer le message. Il est cependant possible de s’ajouter soi-même dans la liste des destinataires afin de pouvoir relire les échanges.
$ echo Autruche | gpg --encrypt --armor --recipient Alice --recipient Bob
La réception
Lorsque Bob reçoit un message chiffré, il lui suffit de demander à GPG
de le déchiffrer en utilisant sa clé privée :
$ gpg --decrypt
# gpg: encrypted with 384-bit ECDH key, ID 412650A16DB5F3C8, created 2021-01-30
# "Bob"
# Autruche
Grand succès, GPG
indique quelques informations concernant le chiffrement et poursuit avec l’animal préféré d’Alice, une Autruche.
Maintenant que Alice et Bob disposent chacun de la clé de chiffrement publique de l’autre, ils peuvent sereinement échanger sans crainte de voir leurs secrets rendus publics.
C’est toute cette mécanique que des services comme Protonmail
rendent transparente :
- Génération de trousseaux.
- Échanges de clés publiques.
- (Dé)chiffrements des échanges.
C’est aussi pour cela qu’il est nécessaire d’utiliser Protonmail
soit dans le navigateur soit via le bridge : la clé privée (dont ils sont garants) est protégée par une phrase de passe. Même si les données sont stockées (chiffrées) sur leurs serveurs, le déchiffrement ne peut se faire que grâce à la phrase de passe qui n’est connue que sur la machine du client.
Échange signé
La clé principale d’Alice dispose des flags S
et C
. Le flag C
a été utilisé plus haut dans ce guide pour permettre à Alice de certifier que la clé publique de Bob est bien valide. Voici maintenant à quoi sert le flag S
de signature.
Dans un cas où les règles de sécurité élémentaires sont respectées, Alice protège sa clé principale. Il est donc raisonnable de penser qu’elle seule en est la propriétaire.
Une clé dotée du flag S
permet d’utiliser la partie privée de la clé pour signer un chiffrement. La partie publique de cette clé permet au reste du monde de vérifier que le message transmis a bien été chiffré par la personne qui transmet ledit message.
En d’autres termes, si Alice se fait voler la sous-clé de (dé)chiffrement (flag E
), le voleur sera capable de déchiffrer les messages à l’attention d’Alice mais ne pourra pas pour autant se faire passer pour elle auprès de Bob.
$ echo Autruche | gpg --encrypt --sign --armor --recipient Bob
# -----BEGIN PGP MESSAGE-----
#
# hJ4DQSZQoW2188gSAwMES+8O1ZhZXlPONP0/5gmbe7HvBzVwk16hHHogN8xIlk74
# jGWZWCNFvKI9xuxezgNcVSTCdp8XzWAbjBLrmU+efL7XjnBwY1VlnXkbkil7VDW4
# PBrNg5uRjCThwxCQR6m7MOlw9WOTDxYcl/zhLJgvZbc/GwSmyfdLY6ZJgT8GEYyv
# 81cgAWCSOsTgvzWRfdr1FNLpAQSoTVFJz6Hwfkek+8AekotYi9QIbD/nRD3ls6x7
# ifOPX47XffUPWeJ4bFkC1m7smqCnGeEE4CkaETLnTGFmnAG0lBlx4ckUVEndPeK6
# ZA/GCdXBB6SaA4VyHZwZRX4SPfvGowhKEacEtFaeTOnKLOFWWcyzEitGff3unG2L
# 2GTwmL2cNX3D00/OjZwgpT5Z8YJCZG/5pIBszxpb60ChsIoQy14bovCnlrV2Tspm
# BCNm/oLZJJV76r3dsgk/n3yA1fRZBq3iP112rNOJ/BRlJsUcdJCk8n8s+J+v+4Yv
# uRtEsdS5X/jt9Rny+xcPWCK34gnegwM0YQnSmUxLiqUDXmTD9WX4GgIolgG4gl8D
# SNJyVACkGigTJr3wu9Hz5hEPuz0VgXWk9a4SCfXufKROQViP9PpjyX4cO8kxmfSL
# 1w61aRTQ7bLhbBMCov7yesyT2QgPv9ENYyeZVuHVnwvjKpdC0eaLEu4i03Dv502s
# b4mkm5l4n7i61JOcHevrVVIZQXN0xF7GsC7z2LRBE8K6er0uqUXdY2nDkBpp6BxK
# RKEbi3Cy9tNkZ4IQYWzrDkdhWEpH2Ipkzeg77MBHnPuOb9GWwJkKvG2LwYHH4P1z
# /q47fjZh/y9DeSWzbVKy3TKTASZb5eguMxpkCAQAMYfqg5vxpPt5OAwShRnM9NpY
# 9q0MhRBbU5VElXtAeDh8
# =sQkW
# -----END PGP MESSAGE-----
En ajoutant l’option --sign
lors du chiffrement, le message chiffré est enrichi de la signature. Au moment de déchiffrer le message sur la machine de Bob, GPG
effectuera aussi une vérification de la signature et préviendra si cette dernière est invalide.
Les trousseaux générés par Protonmail
sont capables de signer les messages envoyés. Cette option n’est pas activée par défaut pour tous les messages (à changer dans les réglages du compte) mais peut être utilisée au cas par cas. Si le destinataire est un compte Protonmail
ou s’il a connaissance de la clé publique dotée du flag S
, il pourra alors être certain que le contenu du mail est digne de confiance.
Mise à jour des dates de validité
Par défaut, la clé principale d’Alice (flags S
et C
) n’est valable que deux ans. Pour ce qui est de Bob, sa sous-clé de chiffrement (flag E
) n’est valide que six mois.
Dans le premier cas, cela signifie que les signatures et certifications d’Alice ne seront plus acceptées par ses destinataires après ces deux années, les clés utilisées ayant expiré. Dans le second cas, cela signifie que la clé de chiffrement de messages destinés à Bob ne pourra plus être utilisée pour chiffrer des messages à son attention au bout de six mois.
Seule la partie publique d’une clé a une date d’expiration. Bob sera toujours capable de déchiffrer les messages reçus auparavant mais plus personne ne lui écrira avec cette clé à partir d’une certaine date.
GPG
permet de mettre à jour les durées de validité des clés publiques en utilisant la clé principale avant de les repartager. Il s’agit d’un mécanisme assez simple permettant de s’assurer que même si la clé principale est perdue, il arrivera un moment ou le trousseau expirera et personne ne cherchera à contacter Bob avec des messages qu’il n’est plus capable de déchiffrer.
$ gpg --edit-key Bob
# gpg (GnuPG) 2.2.27; Copyright (C) 2021 Free Software Foundation, Inc.
# This is free software: you are free to change and redistribute it.
# There is NO WARRANTY, to the extent permitted by law.
#
# Secret key is available.
#
# sec ed25519/DE9A4020694CF411
# created: 2021-01-30 expires: never usage: C
# trust: ultimate validity: ultimate
# ssb brainpoolP384r1/412650A16DB5F3C8
# created: 2021-01-30 expires: 2021-07-29 usage: E
# [ultimate] (1). Bob
#
# gpg> key 1
#
# sec ed25519/DE9A4020694CF411
# created: 2021-01-30 expires: never usage: C
# trust: ultimate validity: ultimate
# ssb* brainpoolP384r1/412650A16DB5F3C8
# created: 2021-01-30 expires: 2021-07-29 usage: E
# [ultimate] (1). Bob
gpg> expire
# Changing expiration time for a subkey.
# Please specify how long the key should be valid.
# 0 = key does not expire
# <n> = key expires in n days
# <n>w = key expires in n weeks
# <n>m = key expires in n months
# <n>y = key expires in n years
# Key is valid for? (0) 1y
# Key expires at Sun 30 Jan 2022 10:23:27 AM CET
# Is this correct? (y/N) y
#
# sec ed25519/DE9A4020694CF411
# created: 2021-01-30 expires: never usage: C
# trust: ultimate validity: ultimate
# ssb* brainpoolP384r1/412650A16DB5F3C8
# created: 2021-01-30 expires: 2022-01-30 usage: E
# [ultimate] (1). Bob
gpg> save
Les étapes sont les suivantes :
- Bob sélectionne la clé
1
, celle de (dé)chiffrement valide six mois. - Il met à jour la période de validité à compter de ce jour à un an.
- Il sauvegarde et quitte
GPG
.
Il doit maintenant indiquer au monde que la durée de validité de sa clé de chiffrement a été mise à jour. C’est là que les serveurs de clés sont extrêmement utiles : il lui suffit de pousser sa clé via gpg --send-keys
pour que l’information soit publique et accessible à quiconque le désire.
Par défaut, les trousseaux générés par Protonmail
n’ont pas de date d’expiration. Il n’y a donc pas à s’occuper de les mettre à jour mais cela peut poser problème en cas de faille de leur côté.
Certificats de révocation
Une autre application des clés principales dotées du flag C
de certification est la révocation des sous-clés.
Générer le certificat de révocation d’une clé se fait en une simple commande :
gpg --generate-revocation Bob --output bob.rev
Ce certificat est à conserver en sécurité, possiblement avec le certificat de révocation de la clé principale. Pour l’utiliser, il suffit de l’importer et de publier les modifications sur les serveurs de clés :
gpg --import bob.rev
gpg --send-keys
Lors de l’import, les clés publiques sont annotées comme révoquées. Lors du partage, le serveur de clés peut transmettre l’information aux autres utilisateurs, leur indiquant ainsi de ne plus utiliser ces clés publiques.
L’usage des certificats de révocation est généralement réservé à deux situations :
- Les clés publiques en circulations sont dépassées, généralement en terme de sécurité, et il est temps de les renouveler.
- Les clés privées ont été compromises et il faut indiquer aux autres personnes qu’elles ne garantissent plus des échanges sûrs ou votre identité sur internet.
Suite à l’usage d’un certificat de révocation, il suffit de générer de nouvelles sous-clés et de les pousser sur les serveurs de clés. Ainsi, la clés principale (et donc l’identité de l’utilisateur) n’est pas compromise mais les sous-clés perdues/volées/dépassées sont mises hors circuit.
Authentification sur machine distante
Ce guide a présenté les flags C
de certification, E
de (dé)chiffrement et S
de signature. Il en existe un dernier, A
pour authentification.
Lorsque l’on cherche à se connecter à une machine distante via SSH
, que ce soit pour de l’administration de serveur, du télé-travail ou simplement pour pousser du code sur un dépôt GIT
, il y a plusieurs méthodes d’authentification. Généralement une paire identifiant/phrase de passe suffit mais une sécurité renforcée sur la machine distante peut demander l’identification par clé publique/clé privée.
GPG
implémente le ssh-agent
qui permet d’utiliser des clés GPG
pour s’identifier auprès de serveurs SSH
de manière transparente. Seule une sous-clé dotée du flag A
dispose de cette fonctionnalité et il est nécessaire d’utiliser le mode expert de GPG
pour la générer.
$ gpg --expert --edit-key Bob
# gpg (GnuPG) 2.2.27; Copyright (C) 2021 Free Software Foundation, Inc.
# This is free software: you are free to change and redistribute it.
# There is NO WARRANTY, to the extent permitted by law.
#
# Secret key is available.
#
# sec ed25519/DE9A4020694CF411
# created: 2021-01-30 expires: never usage: C
# trust: ultimate validity: ultimate
# ssb brainpoolP384r1/412650A16DB5F3C8
# created: 2021-01-30 expires: 2022-01-30 usage: E
# [ultimate] (1). Bob
gpg> addkey
# Please select what kind of key you want:
# (3) DSA (sign only)
# (4) RSA (sign only)
# (5) Elgamal (encrypt only)
# (6) RSA (encrypt only)
# (7) DSA (set your own capabilities)
# (8) RSA (set your own capabilities)
# (10) ECC (sign only)
# (11) ECC (set your own capabilities)
# (12) ECC (encrypt only)
# (13) Existing key
# (14) Existing key from card
Your selection? 11
# Possible actions for a ECDSA/EdDSA key: Sign Authenticate
# Current allowed actions: Sign
#
# (S) Toggle the sign capability
# (A) Toggle the authenticate capability
# (Q) Finished
#
Your selection? s
# Possible actions for a ECDSA/EdDSA key: Sign Authenticate
# Current allowed actions:
#
# (S) Toggle the sign capability
# (A) Toggle the authenticate capability
# (Q) Finished
Your selection? a
# Possible actions for a ECDSA/EdDSA key: Sign Authenticate
# Current allowed actions: Authenticate
#
# (S) Toggle the sign capability
# (A) Toggle the authenticate capability
# (Q) Finished
Your selection? q
# (3) NIST P-256
# (4) NIST P-384
# (5) NIST P-521
# (6) Brainpool P-256
# (7) Brainpool P-384
# (8) Brainpool P-512
# (9) secp256k1
Your selection? 1
# Please specify how long the key should be valid.
# 0 = key does not expire
# <n> = key expires in n days
# <n>w = key expires in n weeks
# <n>m = key expires in n months
# <n>y = key expires in n years
Key is valid for? (0) 1y
Key expires at Sun 30 Jan 2022 10:42:32 AM CET
Is this correct? (y/N) y
Really create? (y/N) y
# We need to generate a lot of random bytes. It is a good idea to perform
# some other action (type on the keyboard, move the mouse, utilize the
# disks) during the prime generation; this gives the random number
# generator a better chance to gain enough entropy.
#
# sec ed25519/DE9A4020694CF411
# created: 2021-01-30 expires: never usage: C
# trust: ultimate validity: ultimate
# ssb brainpoolP384r1/412650A16DB5F3C8
# created: 2021-01-30 expires: 2022-01-30 usage: E
# ssb ed25519/2F26CA16A36818AE
# created: 2021-01-30 expires: 2022-01-30 usage: A
# [ultimate] (1). Bob
gpg> save
Les étapes sont les suivantes :
- La commande
addkey
déclenche l’ajout d’une sous-clé pour le trousseau de Bob. - La sélection
(11) ECC (set your own capabilities)
permet de spécifier manuellement les flags à utiliser.s
suivi deentrée
désactive le flag de signature.a
suivi deentrée
active le flag d’*authentification.q
suivi deentrée
valide le choix.
- Reste ensuite le choix de la courbe elliptique et de la durée de validité comme dans les autres cas.
- La commande
save
sauvegarde et quitteGPG
.
Quelques lignes de configuration sont nécessaires pour utiliser GPG
comme agent SSH
:
> edit ~/.bashrc
# export GPG_TTY="$(tty)"
# export SSH_AUTH_SOCK=$(gpgconf --list-dirs agent-ssh-socket)
# gpgconf --launch gpg-agent
> edit `~/.gnupg/gpg-agent.conf`
# enable-ssh-support
# default-cache-ttl 60
# max-cache-ttl 120
# pinentry-program /usr/bin/pinentry-curses
# ttyname $GPG_TTY
$ gpg --list-key --with-keygrip
# $HOME/.gnupg/pubring.kbx
# -------------------------------
# [...]
# sub ed25519 2021-01-30 [A] [expires: 2022-01-30]
# Keygrip = 1EF3BA236877E7D31CB479151F33793055DB79B1
> edit ~/.gnupg/sshcontrol
# 1EF3BA236877E7D31CB479151F33793055DB79B1
Les étapes sont les suivantes :
- Paramétrer
SSH
pour qu’il utilise l’implémentation deGPG
au lieu de celle par défaut pour la gestion des clés. - Paramétrer
GPG
pour utiliser la fonctionnalité d’agentSSH
. - Trouver le keygrip de la clé d’authentification. Le keygrip est un identifiant liant la clé publique et privée de manière unique.
- Inscrire ce keygrip dans
~/.gnupg/sshcontrol
afin d’indiquer àGPG
quelle clé utiliser. Il s’agit d’une sécurité au cas où plusieurs clés dotées du flagA
sont disponibles.
Désormais, SSH
passera par GPG
pour la gestion des clés d’authentification. Du point de vue de la sécurité, la connexion n’en sera pas changée. Par contre, il est désormais très facile de télécharger la clé publique et de l’ajouter dans le fichier ~/.ssh/authorized_keys
de la machine distante, car elle est en permanence disponnible via les serveurs de clés. À l’usage, cela permet de ne plus transporter que le trousseau GPG
d’une machine à l’autre au lieu de devoir aussi copier les paires de clés SSH
.
Le flag A
n’est donné à aucune clé des trousseaux générés par Protonmail
. Il s’agit d’une fonctionnalité avancée qui intéresse peu leurs clients.
Smart card
La suite de ce guide est parfaitement facultative pour la compréhension et l’usage de GPG
.
Une smart card est un appareil physique chiffré permettant de stocker les sous-clés privées d’un trousseau GPG
. Les algorithmes utilisés par GPG
sont implémentés matériellement, cela permet de ne jamais avoir à faire sortir les sous-clés privées de leur support, augmentant ainsi grandement la sécurité de ces imformations capitales.
En général, la clé principale et son certificat de révocation (seule dotée du flag C
) d’un trousseau sont sauvegardés sur un support chiffré ou même sur papier sous forme d’un QrCode et rangés en sécurité, loin de toute machine accessible via internet. Les sous-clés publiques sont partagées sur un ou plusieurs serveurs de clés pendant que les sous-clés privées sont poussées sur une smart card.
Il y a plusieurs avantages à cette démarche :
- La clé principale, permettant de gérer la validité des autres ne risque pas d’être compromise.
- Les sous-clés privées ne transitent jamais par un support susceptible d’être copié/intercepté.
- La smart card est protégée par une phrase de passe : la possession de l’objet et de la phrase de passe suffit à signer, (dé)chiffrer et authentifier une personne.
$ gpg --edit-key Bob
# gpg (GnuPG) 2.2.27; Copyright (C) 2021 Free Software Foundation, Inc.
# This is free software: you are free to change and redistribute it.
# There is NO WARRANTY, to the extent permitted by law.
#
# Secret key is available.
#
# sec ed25519/0xDE9A4020694CF411
# created: 2021-01-30 expires: never usage: C
# trust: ultimate validity: ultimate
# ssb brainpoolP384r1/0x412650A16DB5F3C8
# created: 2021-01-30 expires: 2022-01-30 usage: E
# ssb ed25519/0x2F26CA16A36818AE
# created: 2021-01-30 expires: 2022-01-30 usage: A
# [ultimate] (1). Bob
gpg> key 1
# sec ed25519/0xDE9A4020694CF411
# created: 2021-01-30 expires: never usage: C
# trust: ultimate validity: ultimate
# ssb* brainpoolP384r1/0x412650A16DB5F3C8
# created: 2021-01-30 expires: 2022-01-30 usage: E
# ssb ed25519/0x2F26CA16A36818AE
# created: 2021-01-30 expires: 2022-01-30 usage: A
# [ultimate] (1). Bob
gpg> keytocard
# Please select where to store the key:
# (2) Encryption key
Your selection? 2
# sec ed25519/0xDE9A4020694CF411
# created: 2021-01-30 expires: never usage: C
# trust: ultimate validity: ultimate
# ssb* brainpoolP384r1/0x412650A16DB5F3C8
# created: 2021-01-30 expires: 2022-01-30 usage: E
# ssb ed25519/0x2F26CA16A36818AE
# created: 2021-01-30 expires: 2022-01-30 usage: A
# [ultimate] (1). Bob
gpg> save
Les étapes sont les suivantes :
- Sélection de la clé à pousser sur la smart card. Ici,
key 1
indique la première sous-clé, celle dotée du flagE
indiquée par un*
par la suite. - La commande
keytocard
demande àGPG
d’envoyer la sous-clé privée sur la smart card. Au cours de cette action, deux phrases de passe sont demandées:- Celle de la sous-clé privée.
- Celle de la smart card. En cas de réussite, la sous-clé et la smart card appartiennent bien à la même personne et le transfert est validé.
- La commande
save
sauvegarde et quitteGPG
.
Le processus de copie doit être répété pour les clés de signature et d’authentification indépendamment. Suite à quoi, il suffit de branche la smart card sur une machine pour que GPG
détecte le trousseau présent dessus et permette de signer, (dé)chiffrer et authentifier le porteur.
Lors de la création de la clé de chiffrement de Bob, le type de courbe Brainpool P-384
a été sélectionné car supporté par la smart card utilisée pour ce guide, une Nitrokey Pro 2. Toutes les courbes ne sont pas supportées car outre la mémorisation de la clé, il faut aussi implémenter de manière sûre les algorithmes directement sur la clé.
Lors du transfert des sous-clés privées vers la smart card, ces dernières sont supprimées de la machine hôte. Il est généralement conseillé d’en garder une copie sur un support sécurisé (autre que celui de la clé principale). En effet, en cas de perte ou vol de la smart card, les clés qui s’y trouvent ne sont plus accessibles.