413 lines
12 KiB
Markdown
413 lines
12 KiB
Markdown
Title: Importer des clefs GnuPG dans sa Nitrockey Pro
|
||
Category: sécurité
|
||
Tags: GPG, open source, open hardware, Nitrokey, pl-fr
|
||
Date: 2019-07-28 23:10
|
||
|
||
Dans un [précédent article]({filename}../decouverte-de-la-nitrokey/index.md)
|
||
j'ai présenté la *Nitrockey Pro* et fait un bref tour du propriétaire. Cette
|
||
fois si je vais expliquer comment y importer des clefs PGP déjà existante.
|
||
|
||
Bien entendu je part sur un système déjà installée et configurée et part du
|
||
principe que la Nitrokey est paramétrée (PIN utilisateur et administrateur, nom
|
||
du propriétaire etc.)
|
||
|
||
## Avant de commencer
|
||
|
||
Mes clefs sont un peu particulières J'ai :
|
||
|
||
- une *clé principale servant* a **créer des sous clefs, de les révoquer et
|
||
de signer celles des copains**.
|
||
- une *sous clé* **permettant de chiffrer**
|
||
- enfin une *sous clé* **permettant de signer**
|
||
|
||
A partir de là nous allons **mettre mes deux sous clefs sur la Nitrokey** et
|
||
garder la clé principale dans un endroit sûr.
|
||
|
||
L'importation n'est pas très difficile et prendra qu'une minute. Par contre il
|
||
est important de réaliser quelques opérations en plus :
|
||
|
||
- créer un certificat de révocations.
|
||
- Sauvegarder comme il se doit la clé maître et ses sous clefs, le certificat
|
||
de révocation. En effet l'opération d'importation de vous sous clefs
|
||
supprimera celles-ci du dossier `~/.GnuPG/`
|
||
- Mettre à l'abri la *Master Key* et la sortir du trousseau *GnuPG* pour la
|
||
mettre en sécurité. Elle sera utile pour révoquer des sous clefs, en
|
||
générer d'autres et certifier.
|
||
|
||
## Réaliser une sauvegarde
|
||
|
||
Avant tout, il est important de garder une copie de sauvegarde de sa clé maître
|
||
et de ses sous clefs au cas ou une manipulations ne se passe pas comme prévue.
|
||
Pour bien faire les choses, exportons les clefs privées, publiques et le
|
||
certificat de révocation dans un fichier compressé et chiffré.
|
||
|
||
Commençons par créer un dossier dans le répertoire `/tmp` afin de recevoir le
|
||
certificat de révocation et les sauvegardes de clefs :
|
||
|
||
```shell
|
||
mkdir /tmp/gpg_backup
|
||
chmod 700 /tmp/gpg_backup
|
||
```
|
||
|
||
### Certificat de révocation
|
||
|
||
Voici la commande utile pour créer un certificat de révocation pour notre clé
|
||
maître :
|
||
|
||
```shell
|
||
gpg --gen-revoke --output /tmp/gpg_backup/revoke.asc <id>
|
||
```
|
||
|
||
Où `<id>` représente l'identifiant de la clé. Une boite de dialogue apparaît
|
||
ensuite demandant la phrase de passe permettant de débloquer la clé privée.
|
||
|
||
### Exporter les clefs
|
||
|
||
Commençons par la clé privée :
|
||
|
||
```shell
|
||
gpg --export-secret-keys --armor --output /tmp/gpg_backup/ephase_private.asc <id>
|
||
```
|
||
|
||
Bien entendu la phrase de passe de la clé sera demandée
|
||
|
||
Puis la clé publique, qui ne nécessite pas de phrase de passe pour être
|
||
débloquée :
|
||
|
||
```shell
|
||
gpg --export --armor --output /tmp/gpg_backup/ephase_public.asc <id>
|
||
```
|
||
|
||
### Créer une archive sécurisée
|
||
|
||
Bien entendu il ne faut pas que ces données (du moins le certificat de
|
||
révocation et la clé privée) tombent entre de mauvaise main, il suffit
|
||
simplement de créer une archive chiffrée du dossier `/tmp/gpg_backup` :
|
||
|
||
```shell
|
||
tar cz -C '/tmp/' gpg_backup | gpg --symmetric --output ephase_key.gpg && rm -rf /tmp/gpg_backup
|
||
```
|
||
|
||
Après avoir rentré un mot de passe de chiffrement fort pour protéger notre
|
||
sauvegarde, nous sommes fin prêt pour la suite des opérations. Pour restaurer le
|
||
dossier il suffira d'utiliser la commande suivante :
|
||
|
||
```shell
|
||
gpg --decrypt ephase_key.gpg | tar xz
|
||
```
|
||
|
||
### Mettre ce fichier à l'abri
|
||
|
||
Le fichier `ephase_key.gpg` sera mis à l'abri sur un espace de stockage hors
|
||
ligne (voire même plusieurs).
|
||
|
||
## Importer la paire de clefs
|
||
|
||
La manipulation se fait depuis la gestion de clefs `gpg`, nous y accédons avec
|
||
la commande :
|
||
|
||
```shell
|
||
gpg --expert --edit-key <id>
|
||
|
||
gpg (GnuPG) 2.2.17; Copyright (C) 2019 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.
|
||
|
||
La clef secrète est disponible.
|
||
|
||
sec rsa4096/XXXXXXXXXXXXXXXX
|
||
créé : 2016-07-07 expire : 2020-07-12 utilisation : SC
|
||
confiance : ultime validité : ultime
|
||
ssb rsa4096/YYYYYYYYYYYYYYYY
|
||
créé : 2016-07-07 expire : 2020-07-12 utilisation : E
|
||
ssb rsa4096/ZZZZZZZZZZZZZZZZ
|
||
créé : 2016-07-07 expire : 2020-07-12 utilisation : S
|
||
[ ultime ] (1). Yorick Barbanneau <ephase@example.com>
|
||
|
||
gpg>
|
||
```
|
||
|
||
À partir de là nous allons procéder par étape :
|
||
|
||
1. choisir la sous clé pour 1 (le chiffrement) et l'exporter dans le slot
|
||
*chiffrement* sur la Nitrokey
|
||
2. choisir la sous clé 2 (signature) et l'exporter dans le slot *signature*
|
||
|
||
La clé maitre sera sortie du trousseau et mise à l'abri.
|
||
|
||
### Exporter la clé ¨Chiffrement¨
|
||
|
||
Voici les commandes à entrer pour exporter la première clé sur la Nitrokey :
|
||
|
||
```shell
|
||
gpg> key 1
|
||
|
||
[...]
|
||
|
||
gpg> keytocard
|
||
```
|
||
|
||
`key 1` permet de dire à `gpg` que l'on travaille sur la première sous clé, et
|
||
`keytocard` envoi celle-ci sur notre *smartcard*
|
||
|
||
`gpg` nous demande de déverrouiller par en entrant la phrase
|
||
de passe et le code *PIN* administrateur de la Nitrokey.
|
||
|
||
|
||
### Exporter la clé ¨Signature¨
|
||
|
||
Il faut maintenant dé-sélectionner la sous clé 1 :
|
||
|
||
```shell
|
||
gpg> key 1
|
||
```
|
||
|
||
Pour copier la clé 2:
|
||
|
||
```shell
|
||
gpg> key 2
|
||
|
||
[...]
|
||
|
||
gpg> keytocard
|
||
```
|
||
|
||
Comme précédemment, `gpg` nous demande de déverrouiller par en entrant la phrase
|
||
de passe et le code *PIN* administrateur de la Nitrokey.
|
||
|
||
### Sauvegarder les changements.
|
||
|
||
Il ne reste plus qu'à sauvegarder nos changement sur les clefs et quitter `gpg`
|
||
|
||
```shell
|
||
gpg> save
|
||
```
|
||
|
||
Les deux sous clefs seront alors supprimées de notre trousseau et disponible
|
||
uniquement via la *smartcard*., d'ailleurs
|
||
|
||
## Mettre sa clé maître à l'abri
|
||
|
||
La clé maître est la plus importante des clefs, elle permet de créer d'autre
|
||
sous clefs, d'émettre des certificats de révocation pour celles-ci ou encore de
|
||
signer les clefs publique des amis.
|
||
|
||
Il est tout à fait possible de la sortir du trousseau pour la mettre à l'abri
|
||
et de la remettre lorsque l'on en a besoin.
|
||
|
||
Pour ma part j'ai choisi de mettre la clé sur un support externe chiffré, et
|
||
avec l'aide d'un script de monter le support lorsque j'en ai besoin et de créer
|
||
un lien symbolique de la clé depuis le répertoire de `GnuPG`.
|
||
|
||
Les outils utilisés sont en général installés de base : `LUKS` et `udisk`
|
||
|
||
### Créer le conteneur chiffré
|
||
|
||
Toutes les opérations suivantes se font en **super utilisateur** ou avec `sudo`.
|
||
|
||
Dans un premier temps partitionnons la clé USB (ici `sdb`):
|
||
|
||
```shell
|
||
parted -s /dev/sdb mklabel msdos mkpart primary ext4 1MiB 100%
|
||
```
|
||
|
||
Il nous faut ensuite créer le conteneur chiffré :
|
||
|
||
```shell
|
||
cryptsetup luksFormat /dev/sdb1
|
||
WARNING!
|
||
========
|
||
Cette action écrasera définitivement les données sur /dev/sdb1.
|
||
|
||
Are you sure? (Type uppercase yes): YES
|
||
Saisissez la phrase secrète pour /dev/sdb1 :
|
||
Vérifiez la phrase secrète :
|
||
```
|
||
|
||
Le déverrouiller :
|
||
|
||
```shell
|
||
cryptsetup luksOpen /dev/sdb1 gpg_master
|
||
Saisissez la phrase secrète pour /dev/sdb1 :
|
||
```
|
||
|
||
Pour le formater :
|
||
|
||
```shell
|
||
mkfs.ext4 -E root_owner=1000:1000 -m 0 /dev/mapper/gpg_master
|
||
```
|
||
Il faut bien entendu adapter le paramètre `root_owner` en fonction de votre
|
||
`UID` et de votre `GID`.
|
||
|
||
Et enfin monter la partition avec :
|
||
|
||
```shell
|
||
mkdir -p /mnt/usb
|
||
mount /dev/mapper/gpg_master /mnt/usb
|
||
```
|
||
|
||
Puis s'assurer que la clé USB ne peut être lue seulement par notre utilisateur :
|
||
|
||
```shell
|
||
chmod 700 /mnt/usb
|
||
```
|
||
|
||
### Déplacer la clé maitre GnuPG sur votre clé USB
|
||
|
||
Les commandes suivante sont à faire dans la foulée mais en tant utilisateur
|
||
courant.
|
||
|
||
Nous allons utilisé une fonctionnalité de `GnuPG 2` : les clefs privées sont
|
||
stockée dans le répertoire `~/.gnupg/private-keys-v1.d/` ou chaque fichier
|
||
correspond à une clé et le nom est repris dans le champs `keygrip` :
|
||
|
||
```shell
|
||
gpg -K --with-keygrip
|
||
/home/ephase/.gnupg/pubring.kbx
|
||
-------------------------------
|
||
sec rsa4096 2016-07-07 [SC] [expire : 2020-07-12]
|
||
3526F4565D76C5674AA56690936CDF3783293949
|
||
Keygrip = ABCDEF1234567890ABCDEF1234567890ABCDEF12
|
||
uid [ ultime ] Yorick Barbanneau <ephase@example.com>
|
||
ssb> rsa4096 2016-07-07 [E] [expire : 2020-07-12]
|
||
Keygrip = FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
|
||
ssb> rsa4096 2016-07-07 [S] [expire : 2020-07-12]
|
||
Keygrip = BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB
|
||
```
|
||
|
||
Je doit donc chercher la clé `3526F4565D76C5674AA56690936CDF3783293949.key` et
|
||
la copier sur notre clé :
|
||
|
||
```shell
|
||
mkdir -p /mnt/usb/.gpg_master
|
||
chown 700 /mnt/usb/.gpg_master
|
||
mv ~/.gnupg/private-keys-v1.d/3526F4565D76C5674AA56690936CDF3783293949.key /mnt/usb/.usbmaster
|
||
```
|
||
|
||
Afin de bien vérifier que la clé n'est plus disponible, il suffit de faire :
|
||
|
||
```shell
|
||
gpg -K
|
||
/home/ephase/.gnupg/pubring.kbx
|
||
-------------------------------
|
||
sec# rsa4096 2016-07-07 [SC] [expire : 2020-07-12]
|
||
3526F4565D76C5674AA56690936CDF3783293949
|
||
uid [ ultime ] Yorick Barbanneau <ephase@example.com>
|
||
ssb> rsa4096 2016-07-07 [E] [expire : 2020-07-12]
|
||
ssb> rsa4096 2016-07-07 [S] [expire : 2020-07-12]
|
||
```
|
||
|
||
Le `#` à côté de `sec` indique que la clé maître n'est plus disponible dans le
|
||
trousseau `GnuPG`.
|
||
|
||
### Automatiser le montage de la clé
|
||
|
||
Afin de faciliter les opération de montage et démontage de la clé USB
|
||
contenant notre clé maître, on va s'aider d'un script.
|
||
|
||
L'utilisation est simple, une fois mis dans un endroit accessible via le `$PATH`
|
||
il suffit de faire `gpgmount.sh m` pour monter la clé USB ou `gpgmount.sh u`
|
||
pour la démonter.
|
||
|
||
```bash
|
||
#!/bin/bash
|
||
|
||
UUID=""
|
||
mountpoint=""
|
||
|
||
usage () {
|
||
cat <<EOF
|
||
$0 m | u
|
||
$0 mount | unmount
|
||
|
||
mount or unmount encrypted device based on UUID and attach private keys
|
||
EOF
|
||
}
|
||
|
||
if [ -L "/dev/disk/by-uuid/${UUID}" ]
|
||
then
|
||
case "$@" in
|
||
"m"|"mount")
|
||
|
||
echo "Mount encryted key"
|
||
action=$(udisksctl unlock -b /dev/disk/by-uuid/${UUID})
|
||
|
||
if [ ! $? -eq 0 ]
|
||
then
|
||
echo $action
|
||
exit 10
|
||
fi
|
||
mountpoint=$(udisksctl mount -b /dev/mapper/luks-${UUID} | \
|
||
awk '{print $4}')
|
||
|
||
while read -r f
|
||
do
|
||
base=$(basename $f)
|
||
|
||
#create symlink to key file if not exist
|
||
if [ ! -e "~/.gnupg/private-keys-v1.d/$base" ]
|
||
then
|
||
ln -s $f ~/.gnupg/private-keys-v1.d/$base
|
||
fi
|
||
done < <(find ${mountpoint%.}/.gpg_master/ -type f -name "*.key")
|
||
;;
|
||
"u"|"unmount")
|
||
echo "unmount encrypted key"
|
||
while read -r f
|
||
do
|
||
rm $f
|
||
done < <(find ~/.gnupg/private-keys-v1.d -type l -name "*.key")
|
||
|
||
udisksctl unmount -b /dev/mapper/luks-${UUID} 2&> /dev/null || \
|
||
echo "Volume is already unmounted"
|
||
udisksctl lock -b /dev/disk/by-uuid/${UUID} 2&> /dev/null || \
|
||
echo "Encrypted container is not unlocked"
|
||
;;
|
||
*)
|
||
echo "parameter not understood, what do you want :"
|
||
usage
|
||
exit 1
|
||
;;
|
||
esac
|
||
else
|
||
echo "USB device $UUID is not connected"
|
||
exit 5
|
||
fi
|
||
|
||
exit 0
|
||
```
|
||
|
||
Il faut bien entendu mettre l'uuid de la partition contenant notre clé maître
|
||
dans la variable `UUID`.
|
||
|
||
Pour le récupérer il suffit de lancer la commande `blkid` en tant que `root`
|
||
avec en paramètre la partition en question:
|
||
|
||
```shell
|
||
blkid /dev/sdb1
|
||
/dev/sdb1: UUID="<uuid>" TYPE="crypto_LUKS" PARTUUID="<partuuid>"
|
||
```
|
||
|
||
## En conlusion
|
||
|
||
J'ai essayé ici de créer un environnement équilibré entre sécurité et facilité.
|
||
La Mitrokey permet donc de sécuriser mes sous clefs utilisées tous les jours
|
||
tout en les rendant disponibles sur mes deux machines principales.
|
||
|
||
Bien sûr il serait plus sécurisé de n'utiliser la clé maître sur une machine
|
||
totalement hors ligne démarrée par une distribution live. Mais avouez que pour
|
||
signer les clé des amis (lors de [chiffro-fête][l_w_cparty] par exemple), ce
|
||
n'est pas l'idéal.
|
||
|
||
[l_w_cparty]:https://fr.wikipedia.org/wiki/CryptoParty
|
||
|
||
## Bibliographie
|
||
|
||
*Kernel Maintainer PGP guide — The Linux Kernel documentation* par Konstantin
|
||
Ryabitsev - [lien][b_pgpkernmaint]
|
||
|
||
*Using an offline GnuPG master key* (2015) par Damien Goutte-Gattat
|
||
- [lien][b_offlinegpgk]
|
||
|
||
[b_pgpkernmaint]:https://www.kernel.org/doc/html/v5.1/process/maintainer-pgp-guide.html
|
||
[b_offlinegpgk]:https://incenp.org/notes/2015/using-an-offline-gnupg-master-key.html
|