Journal OpenPGP, enlarge your privacy

Posté par  . Licence CC By‑SA.
Étiquettes :
23
21
juin
2015

Sommaire

Il y a quelques mois, gouttegd nous faisait un cours magistral sur l'usage d'OpenPGP sur les cartes à puce et récidivait sur le sujet de la gestion des clés.

Ce comportement inadmissible mérite que l'on s'y intéresse de plus près. J'ai donc décidé de me lancer dans l'aventure et de générer moi aussi ma clé PGP. J'espère donc ici apporter un complément aux excellents articles pondus par gouttegd en expliquant comment j'ai posé les premières pierres de mon Web of Trust.

Usage

Bon d'ailleurs, pourquoi faire une clé PGP ? Ben, il parait que l'on peut signer des emails avec. Mais ce n'est pas tout rose.

Lorsque l'on dit : « PGP », on pense le plus souvent : « e-mail ». Mais PGP ne concerne pas que les e-mails. Avec PGP, on peut : chiffrer, signer et authentifier, tout et n'importe quoi. Donc pas uniquement des e-mails.

Le principal usage pour moi sera l'authentification forte en combinant quelque chose que je sais, un mot de passe, combien font : « 2 + 2 », etc…, et quelque chose que j'ai, une paire de couW clés. J'utiliserai cette possibilité pour améliorer l'authentification sur mes serveurs et autres services.

Un autre cas d'usage sera la signature des commits et des tags dans Git.

Support

Je n'avais pas de clé GPG auparavant. Uniquement des clés SSH, en moyenne une par machine cliente utilisée. La multiplication des clés d'authentification n'est pas très optimal car je peux arrêter d'utiliser une machine d'un jour à l'autre, perdre les clés, ou devoir les copier d'une machine à l'autre. Du coup le suivi des clés actives s'avère compliqué.

Stop ! Il me faut une clé pour les gouverner tous. Pour cela je dois toujours posséder cette clé sur moi et pouvoir la transporter en toute sécurité.

J'ai tout simplement opté pour une Yubikey NEO qui à l'avantage d'un grande communauté et qui me permettra aussi de générer des OTP et ainsi bénéficier d'un second facteur d'authentification sur de nombreux services Web.

Ce support sera un peu ma carte d'identité numérique.

Installation

Il faut d'abord installer les outils nécessaires. Bon moi j'utilise Fedora 22 mais vous pourrez sûrement obtenir le même résultat avec d'autres distributions moins performantes.

Nous allons utiliser GnuPGP, dans sa version 2.1 de préférence, l'implémentation libre du standard OpenPGP qui n'est plus à présenter.

Sur Fedora, le paquet gnupg2-smime contient le binaire scdaemon qui permet de communiquer avec la carte. Si vous le cherchez sur Debian, il est dans le paquet gpgsm. De là à comparer GPG et le SM, il n'y a qu'un pas que je vous laisserai franchir dans les commentaires.

# dnf install gnupg2 gnupg2-smime

L'agent GPG est nécessaire au bon fonctionnement du système. Il faut donc s'assurer qu'il soit lancé en même temps que la session utilisateur. Utilisons ce fichier Unit récupéré sur l'excellent Wiki Archlinux.

[Unit]
Description=GnuPG private key agent
IgnoreOnIsolate=true

[Service]
Type=forking
ExecStart=/usr/bin/gpg-agent --homedir=%h/.gnupg --daemon --use-standard-socket
ExecStop=/usr/bin/pkill --uid %u gpg-agent
Restart=on-abort

[Install]
WantedBy=default.target

Mettre cela dans le fichier ~/.config/systemd/user/gpg-agent.service et activer ce nouveau service.

$ systemctl --user enable gpg-agent.service
$ systemctl --user start gpg-agent.service

C'est déjà pas mal pour l'installation de GnuPG. Comme nous l'a clairement expliqué gouttegd, l'accès à la carte ne se fait pas, du moins pas de façon optimale, en direct. pcsc-lite permet de communiquer avec la carte de façon plus efficace.

# dnf install pcsc-lite pcsc-lite-ccid
# systemctl enable pcscd.service
# systemctl start pcscd.service

Voilà ! On devrait être bon niveau installation. Passons à la suite, la configuration de GnuPG.

Configuration de GnuPG

$ man gpg2 | wc -l
2473

2400 lignes, et ça ce n'est que pour la page de manuel. Autant laisser les paramètres de sécurité a ceux dont c'est le métier. Hum…. Il est en effet assez facile de compromettre totalement sa sécurité en changeant un paramètre qui semble anodin.

On peut cependant changer quelques options afin de rendre l'utilisation de gpg2 plus agréable.

# Explicit is better than implicit.
gnupg             # Respecte le standard OpenPGP plus amélioration de compatibilité entre les implémentations.
require-cross-certification     # S'assure que la sous-clé de signature provient bien du trousseau de l'utilisateur.
                                # https://www.gnupg.org/faq/subkey-cross-certify.en.html

no-comments       # Les commentaires c'est mal : https://www.debian-administration.org/users/dkg/weblog/97
no-emit-version   # Exclu la version de gpg lors de l'export des clés.
no-greeting       # Supprime le message de copyright.

armor             # Favorise l'affichage en ASCII blindé.
with-fingerprint  # Mieux vaut vérifier les clés sur leur empreinte.

keyserver hkp://keys.gnupg.net  # DNS Round Robin, pas besoin de plus.

Ça devrait suffire. Si vous avez d'autres paramètres de choix, n'hésitez pas à les partager.

Préparation de la Yubikey

Votre distribution devrait fournir les paquets nécessaires à la configuration de la Yubikey. Il faut donc les installer.

# dnf install yubikey-personalization-gui ykpers

Chez Fedora, le paquet ykpers contient l’outil de de personnalisation en ligne de commande. La première chose à faire est d'activer OpenPGP qui ne l'est pas par défaut.

La Yubikey possède plusieurs modes de fonctionnement. Quatre de ces modes permettent d'activer la carte OpenPGP :

  • 1 : OpenPGP seul ;
  • 2 : OTP + OpenPGP ;
  • 5 : U2F + OpenPGP ;
  • 6 : OTP + U2F + OpenPGP.

En ajoutant 80 aux modes précédents, on active le mode d'éjection automatique de la carte qui permet de (1) éjecter la carte OpenPGP après un certain temps, (2) éjecter la carte lorsqu'un autre mode est actif.

Pour ma part, j'ai choisi d'activer toutes les fonctionnalités de la Yubikey en utilisant le mode 6. Pour faire cela, on fait appel à la commande ykpersonalize.

$ ykpersonalize -m86
Firmware version 3.4.3 Touch level 1797 Program sequence 1

The USB mode will be set to: 0x86

> Commit? (y/n) [n]:y

Configuration du mode OTP

Si vous avez aussi opté pour le mode OTP, la Yubikey vous permettra de stocker 2 configurations distinct. Celles-ci peuvent aussi être configuré par la ligne de commande mais l'interface graphique est plus conviviale.

Dans le premier compartiment de configuration, on va stocker la configuration Yubico OTP en utilisant le mode avancé. Il suffit simplement de générer une identité publique et privée ainsi qu'une clé secrète et de sauvegarder le tout. Je conseille aussi de protéger la configuration par un code secret qui peut être oublié car cette configuration ne devrait plus changer.

Je n'ai pas encore trouvé d'usage pour une seconde configuration mais les possibilités sont les suivantes :

  • OATH-HOTP, qui s'avère avoir quelques faiblesses ;
  • mot de passe statique ;
  • défi/réponse.

Préparer la carte

Encore une fois si vous ne l'avez pas encore fait, jetez un œil à l'article de gouttegd qui explique très bien cette étape et les suivantes. Je vais reprendre ici les étapes que j'ai suivi mais le tout provient globalement de l'article.

On commence donc par définir les paramètres de la cartes.

$ gpg2 --card-edit

Application ID ...: D27600012401020000XXXXXXXXXX0000
Version ..........: 2.0
Manufacturer .....: Yubico
Serial number ....: XXXXXXXXXX
Name of cardholder: [non positionné]
Language prefs ...: [non positionné]
Sex ..............: non indiqué
URL of public key : [non positionné]
Login data .......: [non positionné]
Signature PIN ....: forcé
Key attributes ...: 2048R 2048R 2048R
Max. PIN lengths .: 127 127 127
PIN retry counter : 3 3 3
Signature counter : 0
Signature key ....: [none]
Encryption key....: [none]
Authentication key: [none]
General key info..: [none]

> gpg/carte>

Codes PIN

Bien, commençons par protéger la carte par des codes PIN. Le code PIN administrateur par défaut est 12345678, celui pour lui pour l'utilisateur est 123456.

$ gpg/carte> admin
Les commandes d'administration sont permises

> gpg/carte> passwd
gpg: carte OpenPGP nº D27600012401020000XXXXXXXXXX0000 détectée

1 - change PIN
2 - unblock PIN
3 - change Admin PIN
4 - set the Reset Code
Q - quit

> Quel est votre choix ? 3
PIN changed.

1 - change PIN
2 - unblock PIN
3 - change Admin PIN
4 - set the Reset Code
Q - quit

> Quel est votre choix ? 1
PIN changed.

1 - change PIN
2 - unblock PIN
3 - change Admin PIN
4 - set the Reset Code
Q - quit

> Quel est votre choix ? 4
Reset Code set.

1 - change PIN
2 - unblock PIN
3 - change Admin PIN
4 - set the Reset Code
Q - quit

> Quel est votre choix ? q

> gpg/carte>

Le nombre minimum de chiffres semble être de 8 pour le code administrateur et 6 pour le code utilisateur. J'ai aussi choisi de générer un code de réinitialisation que j'ajouterai sur mon support de sauvegarde des secrets.

J'ai généré mes codes PIN avec la commande suivante :

$ xxd -l 128 -p /dev/urandom | sed -E 's/[^0-9]*//g' | head -c X

X est le nombre de chiffres voulu.

Identification

On va maintenant renseigner les informations sur le propriétaire de la carte.

> gpg/carte> name
Nom du détenteur de la carte : Doe
Prénom du détenteur de la carte : John

> gpg/carte> lang
Préférences de langue : fr

> gpg/carte> sex
Sexe ((M)asculin, (F)éminin ou espace) : M

> gpg/carte> login
Données d'identification (nom du compte) : jdoe

Une fois la clé publique disponible en ligne vous pourrez aussi le renseigner dans la carte avec la commande url.

Génération des clés GPG

Nous y sommes enfin, la génération des clés. Tirez les rideaux, déconnectez vous du réseau, redémarrez la machine et assurez vous d'avoir un minimum de programme en cours de fonctionnement. Ou, installez carrément un système minimal tout frais qui n'a jamais vu à quoi ressemble un câble Ethernet. Il s'agit de s'assurer que la clé privée primaire, reste privée.

On va procéder de la façon suivante :

  • 1 clé primaire RSA de signature, 4096 bits, générée sur la machine ;
    • 1 sous-clé RSA de signature, 2048 bits, générée sur la carte ;
    • 1 sous-clé RSA d'authentification, 2048 bits, générée sur la carte ;
    • 1 sous-clé RSA de chiffrement, 2048 bits, générée sur la carte.

Ou pourra ainsi sauvegarder la clé primaire et la mettre en sécurité hors ligne tout en gardant des sous-clés, inconnues du système car générées par la carte, pour une utilisation quotidienne.

Pour ma passphrase, j'utilise la commande suivante afin de lier un ensemble de mot aléatoirement choisis.

$ for i in `seq 4`; do shuf -n1 /usr/share/dict/words; done | paste -s -d - | tr '[:upper:]' '[:lower:]'
blue-fish-mermaid-copycutter-hurris

Ça permet d'avoir un secret pas trop compliqué à retenir mais difficile à deviner.

Clé primaire

$ gpg2 --full-gen-key
Sélectionnez le type de clef désiré :
   (1) RSA et RSA (par défaut)
   (2) DSA et Elgamal
   (3) DSA (signature seule)
   (4) RSA (signature seule)
> Quel est votre choix ? 4
les clefs RSA peuvent faire une taille comprise entre 1024 et 4096 bits.
Quelle taille de clef désirez-vous ? (2048) 4096
La taille demandée est 4096 bits
Veuillez indiquer le temps pendant lequel cette clef devrait être valable.
         0 = la clef n'expire pas
      <n>  = la clef expire dans n jours
      <n>w = la clef expire dans n semaines
      <n>m = la clef expire dans n mois
      <n>y = la clef expire dans n ans
> Pendant combien de temps la clef est-elle valable ? (0) 3y
La clef expire le XXXXXXXXXXXX
> Est-ce correct ? (o/N) o

GnuPG doit construire une identité pour identifier la clef.

> Nom réel : John Doe
> Adresse électronique : john.doe@example.com
Commentaire : 
Vous avez sélectionné cette identité :
    « John Doe <john.doe@example.com> »

> Changer le (N)om, le (C)ommentaire, l'(A)dresse électronique ou (O)ui/(Q)uitter ? o
De nombreux octets aléatoires doivent être générés. Vous devriez faire
autre chose (taper au clavier, déplacer la souris, utiliser les disques)
pendant la génération de nombres premiers ; cela donne au générateur de
nombres aléatoires une meilleure chance d'obtenir suffisamment d'entropie.
gpg: clef AABBCCDD marquée de confiance ultime.
gpg: répertoire « /home/jdoe/.gnupg/openpgp-revocs.d » créé
les clefs publique et secrète ont été créées et signées.

gpg: vérification de la base de confiance
gpg: 3 marginale(s) nécessaire(s), 1 complète(s) nécessaire(s),
     modèle de confiance PGP
gpg: profondeur : 0  valables :   1  signées :   0
     confiance : 0 i., 0 n.d., 0 j., 0 m., 0 t., 1 u.
gpg: la prochaine vérification de la base de confiance aura lieu le 2018-XX-XX
Remarquez que cette clef ne peut pas être utilisée pour chiffrer. Vous pouvez
utiliser la commande « --edit-key » pour générer une sous-clef à cette fin.
pub   rsa4096/AABBCCDD 2015-XX-XX [expire : 2018-XX-XX]
 Empreinte de la clef = 1234 5678 XXXX XXXX XXXX  XXXX XXXX XXXX XXXX EEFF
uid       [ultimate] John Doe <john.doe@example.com>

> gpg> quit
> Faut-il enregistrer les modifications ? (o/N) o

Pour commencer, j'ai décidé de garder cette clé 3 ans afin de voir comment se passe la prise en main. Je ne saurais que conseiller de sauvegarder la date de renouvellement dans votre calendrier maintenant car il y a peu de chance de s'en rappeler dans 3 ans.

J'ai aussi ajouté ma photographie à la clé. Pour cela, il faut éditer la clé et ajouter un fichier JPEG avec la commande addphoto. Il est conseillé une image de 240x288 pixels et 6 Ko au maximum.

GnuPG fait appel au programme xloadimage pour afficher les photos. Il faut donc s'assurer de l'avoir installé.

# dnf install xloadimage
$ gpg2 --edit-key AABBCCDD

La clef secrète est disponible.

pub  rsa4096/AABBCCDD
     créé : 2015-XX-XX  expire : 2018-XX-XX  utilisation : SC  
     confiance : ultimate      validité : ultimate
[ultimate] (1). John Doe <john.doe@example.com>

> gpg> addphoto

Choisissez une image pour votre photo d'identité. L'image doit être
un fichier JPEG. Rappelez-vous que cette image est stockée dans la
clef publique. Si l'image est très grosse, la clef le sera aussi.
Une taille de l'ordre de 240x288 est conseillée.

> Entrez le nom du fichier JPEG pour la photo d'identité : /home/jdoe/images/id.jpg
> Cette photo est-elle correcte (o/N/q) ? o

pub  rsa4096/AABBCCDD
     créé : 2015-XX-XX  expire : 2018-XX-XX  utilisation : SC  
     confiance : ultimate      validité : ultimate
[ultimate] (1). John Doe <john.doe@example.com>
[ unknown] (2)  [jpeg image of size 4XXX]

> gpg> quit
> Faut-il enregistrer les modifications ? (o/N) o

Sous-clés

C'est maintenant le tour des sous-clés.

$ gpg2 --edit-key AABBCCDD

La clef secrète est disponible.

pub  rsa4096/AABBCCDD
     créé : 2015-XX-XX  expire : 2018-XX-XX  utilisation : SC  
     confiance : ultimate      validité : ultimate
[ultimate] (1). John Doe <john.doe@example.com>
[ultimate] (2)  [jpeg image of size 4XXX]

> gpg> addcardkey
Signature key ....: [none]
Encryption key....: [none]
Authentication key: [none]

Veuillez sélectionner le type de clef à générer :
   (1) Clef de signature
   (2) Clef de chiffrement
   (3) Clef d'authentification
> Quel est votre choix ? 1
Veuillez indiquer le temps pendant lequel cette clef devrait être valable.
         0 = la clef n'expire pas
      <n>  = la clef expire dans n jours
      <n>w = la clef expire dans n semaines
      <n>m = la clef expire dans n mois
      <n>y = la clef expire dans n ans
> Pendant combien de temps la clef est-elle valable ? (0) 1y
La clef expire le XXXXXXXXXXX
> Est-ce correct ? (o/N) o
$ Faut-il vraiment la créer ? (o/N) o

> gpg> addcardkey
Signature key ....: 1234 5678 XXXX XXXX XXXX  XXXX XXXX XXXX XXXX EEFF
Encryption key....: [none]
Authentication key: [none]

Veuillez sélectionner le type de clef à générer :
   (1) Clef de signature
   (2) Clef de chiffrement
   (3) Clef d'authentification
> Quel est votre choix ? 2
Veuillez indiquer le temps pendant lequel cette clef devrait être valable.
         0 = la clef n'expire pas
      <n>  = la clef expire dans n jours
      <n>w = la clef expire dans n semaines
      <n>m = la clef expire dans n mois
      <n>y = la clef expire dans n ans
> Pendant combien de temps la clef est-elle valable ? (0) 1y
La clef expire le XXXXXXXXXXX
> Est-ce correct ? (o/N) o
> Faut-il vraiment la créer ? (o/N) o

> gpg> addcardkey
Signature key ....: 1234 5678 XXXX XXXX XXXX  XXXX XXXX XXXX XXXX EEFF
Encryption key....: 1234 5678 XXXX XXXX XXXX  XXXX XXXX XXXX XXXX EEFF
Authentication key: [none]

Veuillez sélectionner le type de clef à générer :
   (1) Clef de signature
   (2) Clef de chiffrement
   (3) Clef d'authentification
> Quel est votre choix ? 3
Veuillez indiquer le temps pendant lequel cette clef devrait être valable.
         0 = la clef n'expire pas
      <n>  = la clef expire dans n jours
      <n>w = la clef expire dans n semaines
      <n>m = la clef expire dans n mois
      <n>y = la clef expire dans n ans
> Pendant combien de temps la clef est-elle valable ? (0) 1y
La clef expire le XXXXXXXXXXX
> Est-ce correct ? (o/N) o
> Faut-il vraiment la créer ? (o/N) o

pub  rsa4096/AABBCCDD
     créé : 2015-XX-XX  expire : 2018-XX-XX  utilisation : SC  
     confiance : ultimate      validité : ultimate
sub  rsa2048/00112233
     créé : 2015-XX-XX  expire : 2016-XX-XX  utilisation : S   
sub  rsa2048/11223344
     créé : 2015-XX-XX  expire : 2016-XX-XX  utilisation : E   
sub  rsa2048/22334455
     créé : 2015-XX-XX  expire : 2016-XX-XX  utilisation : A   
[ultimate] (1). John Doe <john.doe@example.com>
[ultimate] (2)  [jpeg image of size 4XXX]

> gpg> quit
> Faut-il enregistrer les modifications ? (o/N) o

Voilà, les sous-clés sont sur la carte. J'ai décidé de les garder 1 an. Comme pour la clé primaire, la date de renouvellement est enregistrée dans mon calendrier.

On va vérifier que la certification croisée des clés est bien en place.

$ gpg2 --edit-key AABBCCDD
La clef secrète est disponible.

pub  rsa4096/AABBCCDD
     créé : 2015-XX-XX  expire : 2018-XX-XX  utilisation : SC  
     confiance : ultimate      validité : ultimate
sub  rsa2048/00112233
     créé : 2015-XX-XX  expire : 2016-XX-XX  utilisation : S   
sub  rsa2048/11223344
     créé : 2015-XX-XX  expire : 2016-XX-XX  utilisation : E   
sub  rsa2048/22334455
     créé : 2015-XX-XX  expire : 2016-XX-XX  utilisation : A   
[ultimate] (1). John Doe <john.doe@example.com>
[ultimate] (2)  [jpeg image of size 4XXX]

> gpg> cross-certify
la sous-clef de signature 00112233 a déjà une certification croisée
la sous-clef 11223344 ne signe pas et n'a donc pas besoin de certification croisée
la sous-clef 22334455 ne signe pas et n'a donc pas besoin de certification croisée

> gpg> quit

Voilà, on est bon pour la génération des clés. On peut maintenant la publier.

$ gpg2 --send-key AABBCCDD
gpg: envoi de la clef AABBCCDD au serveur hkp keys.gnupg.net

Conclusion

La génération d'un ensemble de clés OpenPGP n'est pas une tâche aisée. Mais la sécurité viens toujours avec un ensemble de contraintes.

À partir de ce moment, la Yubikey ne me quitte plus. Mais ce n'est pas encore fini. Il reste encore à :

  • protéger notre ensemble de clés en générant des informations de récupération ;
  • enlever la clé primaire du trousseau et de la sauvegarder sur un ou plusieurs supports à tenir secret.

Nous verrons ces étapes dans un prochain article car celui-ci se fait déjà très long.

  • # Trop cool

    Posté par  . Évalué à 9. Dernière modification le 21 juin 2015 à 11:15.

    Une petite question : si je perd ma yubikey après avoir fait tout ça, grâce à la clé primaire je peux régénérer les clés secondaires ? J'imagine que je régénère des clés différentes, mais ce sera transparent dans la pratique ? Ma clé publique n'aura pas changée ? C'est bien ça ?

    Il suffit donc de bien sauvegarder (à la banque ? ;) sa clé primaire et on a pas trop de stress de perdre des mots de passes (enfin sauf celui de la clé primaire d'ailleurs…), de perdre la yubikey, toussa ?

    Ce genre de questions c'est le GROS problème que j'ai avec l'utilisation de clés, voire de mots de passe : je n'ai pas confiance en ma mémoire et en moi pour ne jamais rien perdre ! Je sais bien que c'est le prix de la sécurité, je ne compte pas faire sans, mais ces questions me taraudent :)

    (ps: bonjour, merci :)

    • [^] # Re: Trop cool

      Posté par  . Évalué à 4.

      Temps que la clé primaire est en sécurité, tout va bien. On peut régénérer de nouvelles sous-clés et si l'on possède toujours le certificat, il est possible de révoquer les sous-clés perdues. Cela n'est pas sans conséquences là où ces sous-clés ont été utilisée, mais la toile de confiance reste intacte.

  • # Plus on est de fous…

    Posté par  (site web personnel) . Évalué à 4.

    Content de voir que mes articles font des émules, j’espères que tu vas continuer ;)

    J’ai deux petites remarques à partager sur ce journal.

    Une première, insignifiante, concerne l’unité Systemd utilisé pour démarrer l’agent GnuPG :

    ExecStart=/usr/bin/gpg-agent --homedir=%h/.gnupg --daemon --use-standard-socket
    

    L’option homedir est redondante si tu laisses GnuPG utiliser son dossier par défaut ; et l’option --use-standard-socket est inutile si tu utilises GnuPG 2.1, qui utilises toujours la « socket standard » (l’option n’est restée que par souci de compatibilité avec des scripts écrits pour GnuPG 2.0, mais elle n’a pas d’effets).

    Plus important, le choix de la phrase de passe :

    $ for i in `seq 4`; do shuf -n1 /usr/share/dict/words; done | paste -s -d - | tr '[:upper:]' '[:lower:]'
    blue-fish-mermaid-copycutter-hurris
    

    Ça permet d'avoir un secret pas trop compliqué à retenir mais difficile à deviner.

    Il n’est malheureusement pas sûr que ce secret soit difficile à deviner. Les crackers ont fait beaucoup de progrès au cours des dernières années, et le conseil de xkcd n’est plus forcément valide aujourd’hui, face aux combinator attacks :

    It combines each word in a dictionary with every other word in the dictionary. […] This is an answer to the batteryhorsestaple thing.

  • # « On » est un con !

    Posté par  (site web personnel) . Évalué à -2.

    Lorsque l'on dit : « PGP », on pense le plus souvent : « e-mail ».

    CQFD.

    Adhérer à l'April, ça vous tente ?

Suivre le flux des commentaires

Note : les commentaires appartiennent à celles et ceux qui les ont postés. Nous n’en sommes pas responsables.