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 :

  1. Un trousseau au nom de Alice composé de deux clés :
    1. 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 flags S et C ainsi que comment supprimer ou mettre à jour cette date plus loin dans ce guide.
    2. 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é.
  2. 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 :

  1. 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.
  2. 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 entrant s suivi de entrée, le flag S Sign est désactivé. Entrer q suivi de entrée valide la sélection : une clé uniquement dotée du flag C.
  3. 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.
  4. 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é.
  5. 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 trousseau GPG. 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 :

  1. La commande addkey déclenche l’ajout d’une sous-clé pour le trousseau de Bob.
  2. Le choix (12) ECC (encrypt only) permet de choisir de nouveau la cryptographie sur courbes elliptiques avec uniquement le flag E activé.
  3. L’usage du type de courbe (7) Brainpool P-384 au lieu de (1) Curve 25519 sera expliqué plus tard dans ce guide.
  4. 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.
  5. La commande save sauvegarde les modifications apportées au trousseau de Bob et quitte GPG.

À 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*@@)cP׊V9A%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 :

  1. Bob sélectionne la clé 1, celle de (dé)chiffrement valide six mois.
  2. Il met à jour la période de validité à compter de ce jour à un an.
  3. 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 :

  1. 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.
  2. 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 :

  1. La commande addkey déclenche l’ajout d’une sous-clé pour le trousseau de Bob.
  2. La sélection (11) ECC (set your own capabilities) permet de spécifier manuellement les flags à utiliser.
    1. s suivi de entrée désactive le flag de signature.
    2. a suivi de entrée active le flag d’*authentification.
    3. q suivi de entrée valide le choix.
  3. Reste ensuite le choix de la courbe elliptique et de la durée de validité comme dans les autres cas.
  4. La commande save sauvegarde et quitte GPG.

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 :

  1. Paramétrer SSH pour qu’il utilise l’implémentation de GPG au lieu de celle par défaut pour la gestion des clés.
  2. Paramétrer GPG pour utiliser la fonctionnalité d’agent SSH.
  3. Trouver le keygrip de la clé d’authentification. Le keygrip est un identifiant liant la clé publique et privée de manière unique.
  4. 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 flag A 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 :

  1. Sélection de la clé à pousser sur la smart card. Ici, key 1 indique la première sous-clé, celle dotée du flag E indiquée par un * par la suite.
  2. 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:
    1. Celle de la sous-clé privée.
    2. 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é.
  3. La commande save sauvegarde et quitte GPG.

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.

Divers