Je suis Charlie

Autres trucs

Accueil

Seulement les RFC

Seulement les fiches de lecture

Mon livre « Cyberstructure »

Ève

Ma nouvelle clé PGP

Première rédaction de cet article le 9 février 2014
Dernière mise à jour le 17 juin 2014


Je viens de créer une nouvelle clé PGP, pour authentifier mes messages et pour qu'on puisse m'écrire de manière relativement confidentielle. En même temps, c'était l'occasion de créer une clé conforme aux bonnes pratiques de 2014, tenant compte de l'évolution de la cryptographie. C'est malheureusement plus dur que je ne le pensais.

Mon ancienne clé, portant le key ID 97D6D246 et l'empreinte BE25 EAD6 1B1D CFE9 B9C2 0CD1 4136 4797 97D6 D246 avait en effet été créée il y a treize ans ! Elle utilisait une clé DSA considérée comme trop courte aujourd'hui, vu les progrès de la cryptanalyse, ainsi que des algorithmes de cryptographie trop faibles. Depuis, les craqueurs ont eu tout le temps de trouver la clé privée... Voyons cette ancienne clé avec gpg :


% gpg --edit-key 97D6D246
Secret key is available.

pub  1024D/97D6D246  created: 2000-03-31  expires: never       usage: SC  
                     trust: ultimate      validity: ultimate
sub  2048g/F08F74D7  created: 2000-03-31  expires: never       usage: E   
[ultimate] (1). Stephane Bortzmeyer (Personal address) <stephane@bortzmeyer.org>
...

gpg> showpref
[ultimate] (1). Stephane Bortzmeyer (Personal address) <stephane@bortzmeyer.org>
     Cipher: AES256, AES192, AES, CAST5, 3DES
     Digest: SHA1, SHA256, RIPEMD160
     Compression: ZLIB, BZIP2, ZIP, Uncompressed
     Features: MDC, Keyserver no-modify

Par exemple, 3DES est aujourd'hui déconseillé (mais, on verra plus tard, il ne peut pas être retiré complètement). Il n'existe pas à ma connaissance de moyen simple et en ligne de vérifier la qualité d'une clé PGP, fournissant un service analogue à celui que fournit SSLlabs pour les serveurs TLS (ou, dans un genre différent, ZoneCheck pour les serveurs DNS). Question outils installables localement, il y a les hopenpgp-tools cités tout à la fin de cet article et Parsifal, très riche et très perfectionné mais pas trivial à installer et utiliser. Il faut donc souvent se contenter de l'exploration manuelle, des logiciels non distribués publiquement, et l'aide d'un gourou, si on veut évaluer la qualité d'une clé publique.

Pour générer une nouvelle clé, le point de départ recommandé est en général « Creating the perfect gpg keypair » d'Alex Cabal. Mais on verra que cela ne suffit pas. Personnellement, j'ai fait des choix différents : l'article d'Alex Cabal, comme la plupart des articles sur la génération de clés PGP, donne des exemples en ajoutant des options aux lignes de commande, ou en modifiant les caractéristiques de la clé a posteriori. Cette méthode nécessite de suivre des procédures rigoureuses, et où l'erreur est vite arrivée. Je préfère donc mettre les bonnes pratiques de cryptographie dans le fichier de configuration, ~/.gnupg/gpg.conf :

# Crypto preferences

# For the keys we create
cert-digest-algo SHA256

# For the signatures and other things we generate
default-preference-list SHA512 SHA384 SHA256 SHA224 AES256 AES192 AES ZLIB BZIP2 ZIP Uncompressed

Je ne dirais pas qu'il y a un accord unanime sur les bonnes pratiques (par exemple tout le monde n'omet pas CAST5) mais les choix ci-dessus sont relativement consensuels. Notez que cette option change l'ordre de la liste mais ne supprime pas forcément les algorithmes non cités. Par exemple, je n'ai pas cité SHA-1 mais il se retrouve quand même dans les algorithmes car la norme impose de pouvoir gérer cet algorithme. Sans lui, certains messages PGP parfaitement légaux ne seraient pas lisibles.

Maintenant, commençons l'opération de création d'une clé. Pour limiter un peu (un tout petit peu) le risque d'un logiciel malveillant sur ma machine, j'ai d'abord débranché le câble Ethernet, redémarré l'engin (ce qui ne protège pas, je sais, contre un logiciel malveillant qui s'est installé dans le BIOS, mais c'est une précaution qui ne coûte pas cher et ne peut pas faire de mal). Ensuite :


% gpg ‐‐gen-key
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)
Your selection? 1
RSA keys may be between 1024 and 4096 bits long.
What keysize do you want? (2048) 4096
Requested keysize is 4096 bits
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) 2y
Key expires at Tue Feb  9 12:20:32 2016 CET
Is this correct? (y/N) y

GnuPG needs to construct a user ID to identify your key.

Real name: Stéphane Bortzmeyer
Email address: stephane@bortzmeyer.org
Comment: Main ID
You are using the `utf-8' character set.
You selected this USER-ID:
    "Stéphane Bortzmeyer (Main ID) <stephane@bortzmeyer.org>"

Change (N)ame, (C)omment, (E)mail or (O)kay/(Q)uit? o
You need a Passphrase to protect your secret key.

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: key FEB46FA3 marked as ultimately trusted
public and secret key created and signed.

gpg: checking the trustdb
gpg: 3 marginal(s) needed, 1 complete(s) needed, PGP trust model
gpg: depth: 0  valid:   1  signed:   0  trust: 0-, 0q, 0n, 0m, 0f, 1u
gpg: next trustdb check due at 2016-02-09
pub   4096R/FEB46FA3 2014-02-09 [expires: 2016-02-09]
      Key fingerprint = 1D29 A41C 889B 2E20 80D9  9DB5 2AC5 52F6 FEB4 6FA3
uid                  Stéphane Bortzmeyer (Main ID) <stephane@bortzmeyer.org>
sub   4096R/E8791D6E 2014-02-09 [expires: 2016-02-09]

(Si vous regardez attentivement, vous verrez que ce n'est pas la session qui a généré la nouvelle clé, mais une répétition avec les mêmes paramètres. Ma vraie clé a un autre key ID. Cet article ne montre que des commandes réellements tapées, mais pas forcément celles qui ont créé ma nouvelle clé.) Notez que la longueur de clé RSA proposée par défaut est un peu courte (surtout si la clé doit durer longtemps) et que la clé n'expire pas, par défaut. L'article d'Alex Cabal propose de changer la longueur de clé RSA mais il ne change pas l'expiration, qui fait pourtant partie des bonnes pratiques conseillées (sans elle, en cas de perte de la clé privée, on risque de ne plus pouvoir se débarasser de la clé). Une fois la commande ci-dessus terminée, j'ai désormais une nouvelle clé, de key ID CCC66677 (le joli key ID est un pur coup de chance, je n'ai pas fait un million d'essais pour avoir un résultat esthétique). L'empreinte est F42D 259A 35AD BDC8 5D9B FF3E 555F 5B15 CCC6 6677. Vous pouvez la télécharger ici (ce fichier a été produit par gpg --armor --export CCC66677) ou bien, si vous avez les bonnes autorités de certification, en HTTPS ici.

Alex Cabal suggère ensuite de créer des sous-clés (un bon article chez Debian explique leur utilité). C'est aussi simple que (ici, pour une clé dédiée aux signatures) :


% gpg --edit-key 2ED6226D
gpg> addkey
Key is protected.

You need a passphrase to unlock the secret key for
user: "Stéphane Bortzmeyer (Main ID) <stephane@bortzmeyer.org>"
4096-bit RSA key, ID 2ED6226D, created 2014-02-09

Please select what kind of key you want:
   (3) DSA (sign only)
   (4) RSA (sign only)
   (5) Elgamal (encrypt only)
   (6) RSA (encrypt only)
Your selection? 4
RSA keys may be between 1024 and 4096 bits long.
What keysize do you want? (2048) 4096
Requested keysize is 4096 bits
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) 2y
Key expires at Tue Feb  9 18:40:19 2016 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.
...
sub  4096R/7B5BCD86  created: 2014-02-09  expires: 2016-02-09  usage: S   
...

Et pour créer d'autres identités :


gpg> adduid
Real name: Stéphane Bortzmeyer
Email address: stephane@abgenomica.com
Comment: 
You are using the `utf-8' character set.
You selected this USER-ID:
    "Stéphane Bortzmeyer <stephane@abgenomica.com>"

Change (N)ame, (C)omment, (E)mail or (O)kay/(Q)uit? o

You need a passphrase to unlock the secret key for
...

Une fois qu'on est satisfait de sa clé (mais rappelez-vous qu'il n'y a hélas pas de moyen simple de la tester), vous pouvez la signer avec l'ancienne clé (97D6D246), pour certifier la nouvelle clé (CCC66677) :

% gpg --default-key 97D6D246 --sign-key CCC66677

Il reste à l'envoyer aux serveurs de clés :

% gpg  --send-keys CCC66677 
gpg: sending key CCC66677 to hkp server pool.sks-keyservers.net

Et la clé est désormais disponible pour tout le monde.

Si on n'a pas modifié son ~/.gnupg/gpg.conf à l'avance, comme je le recommande, il faut durcir les choix d'algorithmes utilisés après, comme recommandé par Alex Cabal.


% gpg --edit-key CCC66677
Secret key is available.

pub  4096R/CCC66677  created: 2014-02-08  expires: 2016-02-08  usage: SC  
                     trust: ultimate      validity: ultimate
sub  4096R/F9054A15  created: 2014-02-08  expires: never       usage: E   
[ultimate] (1). Stéphane Bortzmeyer (Main key) <stephane@bortzmeyer.org>

gpg> setpref SHA512 SHA384 SHA256 SHA224 AES256 AES192 AES ZLIB BZIP2 ZIP Uncompressed
Set preference list to:
     Cipher: AES256, AES192, AES, 3DES
     Digest: SHA512, SHA384, SHA256, SHA224, SHA1
     Compression: ZLIB, BZIP2, ZIP, Uncompressed
     Features: MDC, Keyserver no-modify
Really update the preferences for the selected user IDs? (y/N) y

You need a passphrase to unlock the secret key for
user: "Stéphane Bortzmeyer (Main key) <stephane@bortzmeyer.org>"
4096-bit RSA key, ID CCC66677, created 2014-02-08

...

Important : faites cette opération avant d'ajouter (éventuellement) d'autres identités, sinon ces autres identités garderont la vieille liste. Tout ça est compliqué, avec ces commandes qui dépendent de l'ordre exact d'exécution ? Oui, je trouve aussi et c'est pour cela que je préfère ma méthode, exposée au début de cet article.

Changer les préférences ne marche pas pour la clé elle-même et les sous-clés, déjà créées à ce stade. Si on n'utilise pas la méthode que je recommande (modifier ~/.gnupg/gpg.conf) avant, et qu'on veut remplacer SHA-1 par le plus sûr SHA-256, il faudra dans ce cas le faire après, en détruisant les signatures et en les refaisant :


% gpg  --cert-digest-algo SHA256 --edit-key F9054A15  
Secret key is available.

pub  4096R/CCC66677  created: 2014-02-08  expires: 2016-02-08  usage: SC  
                     trust: ultimate      validity: ultimate
sub  4096R/F9054A15  created: 2014-02-08  expires: never       usage: E   
sub  4096R/42EE189F  created: 2014-02-08  expires: never       usage: S   
[ultimate] (1). Stéphane Bortzmeyer (Main key) <stephane@bortzmeyer.org>
[ultimate] (2)  Stéphane Bortzmeyer <stephane@sources.org>
[ultimate] (3)  Stéphane Bortzmeyer (Work address) <bortzmeyer@nic.fr>

gpg> uid 1

pub  4096R/CCC66677  created: 2014-02-08  expires: 2016-02-08  usage: SC  
                     trust: ultimate      validity: ultimate
sub  4096R/F9054A15  created: 2014-02-08  expires: never       usage: E   
sub  4096R/42EE189F  created: 2014-02-08  expires: never       usage: S   
[ultimate] (1)* Stéphane Bortzmeyer (Main key) <stephane@bortzmeyer.org>
[ultimate] (2)  Stéphane Bortzmeyer <stephane@sources.org>
[ultimate] (3)  Stéphane Bortzmeyer (Work address) <bortzmeyer@nic.fr>

gpg> delsig
uid  Stéphane Bortzmeyer (Main key) <stephane@bortzmeyer.org>
sig!3        CCC66677 2014-02-09  [self-signature]
Delete this good signature? (y/N/q)y
Really delete this self-signature? (y/N)y
uid  Stéphane Bortzmeyer (Main key) <stephane@bortzmeyer.org>
sig!3        97D6D246 2014-02-08  Stephane Bortzmeyer (Personal address) <stepha
Delete this good signature? (y/N/q)n
Deleted 1 signature.

gpg> sign

pub  4096R/CCC66677  created: 2014-02-08  expires: 2016-02-08  usage: SC  
                     trust: ultimate      validity: ultimate
 Primary key fingerprint: F42D 259A 35AD BDC8 5D9B  FF3E 555F 5B15 CCC6 6677

     Stéphane Bortzmeyer (Main key) <stephane@bortzmeyer.org>

Are you sure that you want to sign this key with your
key "Stéphane Bortzmeyer (Main key) <stephane@bortzmeyer.org>" (CCC66677)

This will be a self-signature.

Really sign? (y/N) y

You need a passphrase to unlock the secret key for
user: "Stéphane Bortzmeyer (Main key) <stephane@bortzmeyer.org>"
4096-bit RSA key, ID CCC66677, created 2014-02-08

(Et idem pour toutes les identités.)

Un petit mot sur l'expiration : contrairement à ce qu'on voit dans l'article d'Alex Cabal, j'ai mis une durée de validité et ma clé va donc expirer dans deux ans. Devrais-je en regénerer dans deux ans ? Non, on peut toujours renouveller sa clé et, contrairement aux noms de domaine ou aux certificats X.509, c'est gratuit :


%  gpg --edit-key 2ED6226D
...
gpg> expire
Changing expiration time for the primary key.
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) 2y
Key expires at Tue Feb  9 20:55:44 2016 CET
Is this correct? (y/N) y
...
gpg> save

% gpg --send-keys 2ED6226D

Et on est reparti pour deux ans. Il « suffit » donc de ne pas oublier ce renouvellement.

Quelques bonnes références à lire : les options de configuration de GnuPG et les options les plus baroques de ce logiciel et le RFC 4880 pour tout connaître des formats utilisés par PGP. Et un autre exemple de génération de clé, bien plus parano. Voir aussi un très bon article sur les bonnes pratiques PGP où j'ai découvert cet utile outil hopenpgp-tools pour tester la qualité de sa clé :

% hkt export-pubkeys  'F42D 259A 35AD BDC8 5D9B  FF3E 555F 5B15 CCC6 6677'|hokey lint
...
Key has potential validity: good
...
Checking to see if key is RSA or DSA (>= 2048-bit): RSA 4096
...
  Stéphane Bortzmeyer (Main key) <stephane@bortzmeyer.org>:
    Self-sig hash algorithms: [SHA256]
    Preferred hash algorithms: 
      [SHA512,SHA384,SHA256,SHA224,SHA1]
    Key expiration times: 
      [1y11m30d14925s = Mon Feb  8 21:40:05 UTC 2016]
...

Merci à Florian Maury pour m'avoir encouragé à changer ma clé et à essayer d'en faire une « parfaite », et merci aussi pour son aide lors d'un travail difficile.

Version PDF de cette page (mais vous pouvez aussi imprimer depuis votre navigateur, il y a une feuille de style prévue pour cela)

Source XML de cette page (cette page est distribuée sous les termes de la licence GFDL)