Add GnuPG keys export to Nitrokey
This commit is contained in:
parent
8e625fff00
commit
d055d1ee97
1 changed files with 413 additions and 0 deletions
|
@ -0,0 +1,413 @@
|
||||||
|
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
|
Loading…
Add table
Add a link
Reference in a new issue