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)
...
gpg> showpref
[ultimate] (1). Stephane Bortzmeyer (Personal address)
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
= key expires in n days
w = key expires in n weeks
m = key expires in n months
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) "
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)
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) "
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
= key expires in n days
w = key expires in n weeks
m = key expires in n months
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 "
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)
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) "
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)
[ultimate] (2) Stéphane Bortzmeyer
[ultimate] (3) Stéphane Bortzmeyer (Work address)
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)
[ultimate] (2) Stéphane Bortzmeyer
[ultimate] (3) Stéphane Bortzmeyer (Work address)
gpg> delsig
uid Stéphane Bortzmeyer (Main key)
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)
sig!3 97D6D246 2014-02-08 Stephane Bortzmeyer (Personal address) 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)
Are you sure that you want to sign this key with your
key "Stéphane Bortzmeyer (Main key) " (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) "
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
= key expires in n days
w = key expires in n weeks
m = key expires in n months
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) :
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.