généralitées
max@host % gpg --list-secret-keys --with-subkey-fingerprint
/home/max/.gnupg/pubring.kbx
----------------------------
sec# rsa4096 2012-10-01 [SC] [revoked: 2017-02-06]
60ADE6F57D9B2DE4B4B339DDD9372AFD10931D71
uid [ revoked] Maxime de Roucy <maxime.deroucy@gmail.com>
uid [ revoked] Maxime de Roucy <maxime1986@wanadoo.fr>
uid [ revoked] Maxime de Roucy <maxime.deroucy@oxalide.com>
sec# rsa4096 2018-12-16 [SC]
4F3897929DE4618301B426673803C67BA14CE632
uid [ultimate] Maxime de Roucy <maxime.deroucy@oxalide.com>
uid [ultimate] Maxime de Roucy <maxime.deroucy@gmail.com>
uid [ultimate] Maxime de Roucy <maxime.deroucy@fr.clara.net>
ssb# rsa4096 2018-12-16 [E]
835E5E07C7907569F38768A734C5FD5D631B4403
ssb rsa4096 2018-12-16 [S]
36F94EE7AB8DB18046C022E65FFA526C839248CB
ssb rsa4096 2018-12-16 [E]
AE0F1925441657AA46713F1DE9F162D1E102E412
Ici j’ai deux master keys (secret key: sec), l’une est révoquée (60ADE6F57D9B2DE4B4B339DDD9372AFD10931D71), l’autre est encore valide (4F3897929DE4618301B426673803C67BA14CE632).
max@host % gpg --list-secret-keys --with-subkey-fingerprint 4F3897929DE4618301B426673803C67BA14CE632
sec# rsa4096 2018-12-16 [SC]
4F3897929DE4618301B426673803C67BA14CE632
uid [ultimate] Maxime de Roucy <maxime.deroucy@oxalide.com>
uid [ultimate] Maxime de Roucy <maxime.deroucy@gmail.com>
uid [ultimate] Maxime de Roucy <maxime.deroucy@fr.clara.net>
ssb# rsa4096 2018-12-16 [E]
835E5E07C7907569F38768A734C5FD5D631B4403
ssb rsa4096 2018-12-16 [S]
36F94EE7AB8DB18046C022E65FFA526C839248CB
ssb rsa4096 2018-12-16 [E]
AE0F1925441657AA46713F1DE9F162D1E102E412
Cette master key permet de :
- S: signer
- C: créer des sous clées et des certificat de revocation, etc.
Le suffix #
indique que la clé n’est pas réellement présente dans le homedir.
Le suffix >
indique que la clé est stoqué sur une smartcard (dans cette exemple je n’en ai pas).
Trois sub-keys (secret sub-key: ssb) lui sont associée :
- 835E5E07C7907569F38768A734C5FD5D631B4403 qui permet de chiffrer (E) et qui pas réellement présente dans le homedir (#)
- 36F94EE7AB8DB18046C022E65FFA526C839248CB qui permet de signer (S)
- AE0F1925441657AA46713F1DE9F162D1E102E412 qui permet de chiffrer (E)
Je n’est pas trouvé de moyen simple d’associer un commentaire à chaque sous-clé (e.g. pour définir son usage).
homedir
A chaque fois que vous switché de homedir, je vous conseil de kill le gpg-agent
(l’agent est restart automatiquement sur le homedir suivant).
gpg …
pkill gpg-agent
gpg --homedir X …
pkill gpg-agent
gpg --homedir Y …
pkill gpg-agent
gpg …
subkey
Source: man gpg
Pour forcé l’utilisation/l’export/… d’une subkey en particulier il faut suffixer sont ID/Hash d’un !
:
When using gpg an exclamation mark (!) may be appended to force using the specified primary or secondary key and not to try and calculate which primary or secondary key to use.
Dans cette exemple, ces deux clés sont des subkey d’une même clé master :
max@host % gpg --encrypt-files -r '6FD22AB720151CD0672B9AA4BB579231A3659CFD' -r '7FD6798B5B230D994DF42AB9969DC552FBA21F06' toto
gpg: 6FD22AB720151CD0672B9AA4BB579231A3659CFD : ignoré : clef publique déjà présente
→ toto
est chiffré avec une clé choisi par gpg (même pas sur que ça soit l’une des deux mensionnée)
max@host % gpg --encrypt-files -r '6FD22AB720151CD0672B9AA4BB579231A3659CFD!' -r '7FD6798B5B230D994DF42AB9969DC552FBA21F06!' toto
→ OK, toto
est chiffré avec les deux clé indiqué en paramètre
précautions
Il est recommandé de ne pas utilisé la master key pour autre chose que créer les subkeys et sont propre certificat de révocation. De plus la master key devrait être stocké dans un endroit particulièrement sécurisé (pas le homedir standard quoi), genre une clé usb ou du papié dans un coffre, une smartcard… Personnellement j’ai choisi d’utiliser du papier… par ce que je suis radin ☺
Il n’est pas possible de supprimer une sous-clé d’un homedir sans supprimer la clé principal (2023/07/16 apparement c’est fixed). En revanche il est possible d’exporté une ou plusieurs sous-clés. Je ne veut pas que ma master key soit disponible dans mon homedir par défault. Je créé donc un homedir temporaire dans lequel je créé la master key et toutes les subkeys. J’export les subkeys et les importes dans les homedir pour lesquel elles sont destinées (la subkey de mon ordi sur l’ordi, la subkey du téléphone sur le téléphone…). Puis j’export la master key et toutes ses subkeys sous forme de paperkey (ASCII mais aussi QR Code ; je détaille la procédure dans la suite de l’article. Et je supprime le homedir temporaire.
password
ajout
max@host % gpg --homedir … --edit-key 4F3897929DE4618301B426673803C67BA14CE632
…
gpg> passwd
gpg m’a demandé quatre password, un pour la master key et un pour chaque subkey.
Il est possible de mettre des password différent pour chaque key sec & ssb… mais je le deconseille (en tout cas dans un même homedir).
Pour ajouter un password sur seul des subkey :
max@host % gpg --homedir gnupg-test --edit-key 4F3897929DE4618301B426673803C67BA14CE632
…
gpg> key 9C52A3B4E78EBB7E
… un * devrait apparaitre sur la ligne de la subkey …
gpg> passwd
modification
max@host % gpg --homedir gnupg-test --edit-key 4F3897929DE4618301B426673803C67BA14CE632
…
gpg> passwd
Il s’agit de la même commande que pour ajouter un mot de passe à une clé qui n’en possède pas, mais ici gpg applique le même mot de passe pour toutes les key sec & ssb ; il ne demande qu’une seul fois le nouveau mot de passe.
Pour changer le password d’une seul des subkey :
max@host % gpg --homedir … --edit-key 4F3897929DE4618301B426673803C67BA14CE632
…
gpg> key 9C52A3B4E78EBB7E
… un * devrait apparaitre sur la ligne de la subkey …
gpg> passwd
suppression
Note 2023/07/16: apparement il n’y a plus besoin d’utiliser --pinentry-mode loopback
max@host % gpg --homedir gnupg-test --pinentry-mode loopback --edit-key 4F3897929DE4618301B426673803C67BA14CE632
…
gpg> passwd
L’option --pinentry-mode loopback
indique à gpg qu’il doit demander lui-même le mot de passe (sans utiliser d’outil externe).
Vous devrez donc voir plusieurs prompt Enter passphrase:
, le premier vous demandant le password actuelle, les autres les nouveaux password (un pour chaque key sec & ssb).
Il suffit d’indiquer un password vide pour le supprimer.
check password
Pour verifier qu’un clé/sous-clé est bien protégé par mot de passe.
sous-clé de signature
pkill gpg-agent ; echo "1234" | gpg --armor --local-user '36F94EE7AB8DB18046C022E65FFA526C839248CB!' --sign - > /dev/null && echo "The correct passphrase was entered for this key" ; pkill gpg-agent
Je fait des pkill gpg-agent
pour forcer la création de nouveau agent et clear tout les caches éventuel.
sous-clé de chiffrement
pkill gpg-agent ; echo "1234" | gpg --armor --recipient 'AE0F1925441657AA46713F1DE9F162D1E102E412!' --encrypt - | gpg --decrypt - ; pkill gpg-agent
Je fait des pkill gpg-agent
pour forcer la création de nouveau agent et clear tout les caches éventuel.
key-server
Il faut utiliser hkps://keys.openpgp.org et pas les autres serveur
C’est pour éviter une attack de certificate poisoning (?).
send-keys
Avec le serveur hkps://keys.openpgp.org pour upload ses clé public il faut utiliser :
gpg --export 4F3897929DE4618301B426673803C67BA14CE632 | curl -T - https://keys.openpgp.org
source: https://keys.openpgp.org/about/usage#gnupg-upload
generer une nouvelle clé privé
generer la subkey dans le repo “secure” (ici gnupg-master) qui ne doit pas être stocké sur la machine (genre une clé usb), sans password :
gpg --homedir gnupg-master --edit-key 4F3897929DE4618301B426673803C67BA14CE632
…
gpg> addkey
…
ssb rsa4096/F1A963424748BDEF
…
gpg> save
Copier le repo temporairement et ajouter un password :
cp -a gnupg-master to_remove
gpg --homedir to_remove --edit-key 4F3897929DE4618301B426673803C67BA14CE632
…
gpg> key F1A963424748BDEF
…
gpg> passwd
…
gpg> save
export la subkey et remove le dossier temporaire :
gpg --homedir to_remove --list-secret-keys --with-subkey-fingerprint 4F3897929DE4618301B426673803C67BA14CE632
…
B4139B22F599101254779AAAF1A963424748BDEF
…
gpg --homedir to_remove --export-secret-subkeys 'B4139B22F599101254779AAAF1A963424748BDEF!' > galaxy-a7.gpg
rm -r to_remove
paperkey
Sources: https://wiki.archlinux.org/title/Paperkey
backup
Attention, les (sous)clé protégées par mot de passe sont exportées avec leur protection. Pour avoir un export sans mot de passe il faut d’abord supprimer le password des (sous)clé dans le keyring source (ce que je ne montre pas ici).
Export de la clé principale et d’une des sous-clé qui me servent à chiffrer mes passwords :
gpg --homedir gnupg-master --export-secret-keys '4F3897929DE4618301B426673803C67BA14CE632!' 'AE0F1925441657AA46713F1DE9F162D1E102E412!' > 4F3897929DE4618301B426673803C67BA14CE632.gpg
ou
gpg --homedir gnupg-master --export-secret-keys 'AE0F1925441657AA46713F1DE9F162D1E102E412!' > 4F3897929DE4618301B426673803C67BA14CE632.gpg
Pas besoin de spécifier la clé princial, --export-secret-keys
l’export de toute façon.
Export de la clé principale uniquement :
gpg --homedir gnupg-master --export-secret-keys '4F3897929DE4618301B426673803C67BA14CE632!' > 4F3897929DE4618301B426673803C67BA14CE632.gpg
Export d’une subkey uniquement (sans la clé principal) :
gpg --homedir gnupg-master --export-secret-keys '716DAE0D56BB01B30A72C5BCE6B6DA98337A3C7C!' > 716DAE0D56BB01B30A72C5BCE6B6DA98337A3C7C.gpg
Verification que l’imprimante est bien detectée :
lpstat -p -d
printer Samsung-M2070 is idle. enabled since dim. 02 juil. 2023 18:17:55
system default destination: Samsung-M2070
ASCII
Export au format ASCII :
paperkey --secret-key 4F3897929DE4618301B426673803C67BA14CE632.gpg --output paperkey.ascii
Impression :
lpr -o fit-to-page -o media=a4 paperkey.ascii
QRCode
Export brute :
paperkey --secret-key 4F3897929DE4618301B426673803C67BA14CE632.gpg --output-type raw --output paperkey.raw
qrencode permet de split automatiquement le fichier avec l’option --structured
, mais je n’ai trouvé aucune qrcode reader permettant de lire les fichier généré.
Le plus simple et de passer le fichier en base64 (pour être en alphanumeric) et de split :
base64 -w0 paperkey.raw > paperkey.raw.base64
split -b 1273 paperkey.raw.base64 paperkey.raw.base64.split.
1273 est la taille maximal autorisé dans notre cas :
- https://github.com/fukuchi/libqrencode/blob/master/qrspec.c#L100
- https://github.com/fukuchi/libqrencode/blob/master/qrspec.c#L54
- https://github.com/fukuchi/libqrencode/blob/master/qrspec.c#L43
Pour le mode alphanum standard, version 40, level H : 3706 - 2430 = 1276 Mais en fait le qrcode à besoin de 3 octet pour stoqué le mode et la taille, ce qui nous donne 1273.
Encodage des fichiers :
for i in paperkey.raw.base64.split.*
do
qrencode --symversion=40 --level=H --read-from=$i --output=$i.png
done
Impression :
lpr -o fit-to-page -o media=a4 paperkey.raw.base64.split.*.png
restore
Il faut récupérer 4F3897929DE4618301B426673803C67BA14CE632 et le convertir au format gpg:
wget -O 4F3897929DE4618301B426673803C67BA14CE632.pub https://keys.openpgp.org/vks/v1/by-fingerprint/4F3897929DE4618301B426673803C67BA14CE632
gpg --dearmor 4F3897929DE4618301B426673803C67BA14CE632.pub
On obtient le fichier 4F3897929DE4618301B426673803C67BA14CE632.pub.gpg
ascii
cat paperkey.ascii | paperkey --pubring 4F3897929DE4618301B426673803C67BA14CE632.pub.gpg --output 4F3897929DE4618301B426673803C67BA14CE632.gpg
gpg --import 4F3897929DE4618301B426673803C67BA14CE632.gpg
qrcode
zbarimg --raw *.png | base64 -d | paperkey --pubring 4F3897929DE4618301B426673803C67BA14CE632.pub.gpg --output 4F3897929DE4618301B426673803C67BA14CE632.gpg
gpg --import 4F3897929DE4618301B426673803C67BA14CE632.gpg
verification
pass gpg/master
ou
gpg --decrypt ~/.password-store/gpg/master.gpg
→ all good
notes
J’ai essayé datamatrix (paquet dmtx-utils
) mais dmtxread
n’arrive plus à lire les fichier une fois imprimé/scanné.
notes
certificat
utiliser un certificat de revokation : https://mwl.io/archives/2192
list-packkets
gpg --list-packets …fichier…
Permet d’afficher exactement le contenu d’un fichier.
…dummy…: indique que les metadata sont là mais pas la clé en elle meme
gpg-connect-agent
max@host % gpg-connect-agent 'help keyinfo' /bye
# KEYINFO [--[ssh-]list] [--data] [--ssh-fpr] [--with-ssh] <keygrip>
#
# Return information about the key specified by the KEYGRIP. If the
# key is not available GPG_ERR_NOT_FOUND is returned. If the option
# --list is given the keygrip is ignored and information about all
# available keys are returned. If --ssh-list is given information
# about all keys listed in the sshcontrol are returned. With --with-ssh
# information from sshcontrol is always added to the info. Unless --data
# is given, the information is returned as a status line using the format:
#
# KEYINFO <keygrip> <type> <serialno> <idstr> <cached> <protection> <fpr>
#
# KEYGRIP is the keygrip.
#
# TYPE is describes the type of the key:
# 'D' - Regular key stored on disk,
# 'T' - Key is stored on a smartcard (token),
# 'X' - Unknown type,
# '-' - Key is missing.
#
# SERIALNO is an ASCII string with the serial number of the
# smartcard. If the serial number is not known a single
# dash '-' is used instead.
#
# IDSTR is the IDSTR used to distinguish keys on a smartcard. If it
# is not known a dash is used instead.
#
# CACHED is 1 if the passphrase for the key was found in the key cache.
# If not, a '-' is used instead.
#
# PROTECTION describes the key protection type:
# 'P' - The key is protected with a passphrase,
# 'C' - The key is not protected,
# '-' - Unknown protection.
#
# FPR returns the formatted ssh-style fingerprint of the key. It is only
# printed if the option --ssh-fpr has been used. It defaults to '-'.
#
# TTL is the TTL in seconds for that key or '-' if n/a.
#
# FLAGS is a word consisting of one-letter flags:
# 'D' - The key has been disabled,
# 'S' - The key is listed in sshcontrol (requires --with-ssh),
# 'c' - Use of the key needs to be confirmed,
# '-' - No flags given.
#
# More information may be added in the future.
OK
max@host % gpg-connect-agent 'keyinfo --list' /bye
S KEYINFO 83A2BB6DB2D632E92EDFFD9A6F278134D2C76012 D - - - P - - -
S KEYINFO 3BF18C02C764451AD7CBD6504ED7936E571BB87C D - - - P - - -
S KEYINFO 7AD225A04E857C1FEA6D0C687D75848692D56CF5 D - - - P - - -
S KEYINFO D945ADA023667FCAFD9305552B3DBA6286946FD9 D - - - P - - -
S KEYINFO F0F148EF8B2A7A35BA48F175F861883BF3F5848E D - - - C - - -
S KEYINFO 3D60E5ADEDB55BFC10E7F212728C8C17E4D489F7 D - - - C - - -
S KEYINFO FF73871150A205DF1BC63A1F28544C9244749DFB D - - 1 P - - -
OK
max@host % l ~/.gnupg/private-keys-v1.d
total 28K
-rw------- 1 max users 2,1K 6 févr. 2017 3BF18C02C764451AD7CBD6504ED7936E571BB87C.key
-rw------- 1 max users 977 6 juin 19:40 3D60E5ADEDB55BFC10E7F212728C8C17E4D489F7.key
-rw------- 1 max users 2,1K 8 févr. 2017 7AD225A04E857C1FEA6D0C687D75848692D56CF5.key
-rw------- 1 max users 2,1K 6 févr. 2017 83A2BB6DB2D632E92EDFFD9A6F278134D2C76012.key
-rw------- 1 max users 2,1K 8 févr. 2017 D945ADA023667FCAFD9305552B3DBA6286946FD9.key
-rw------- 1 max users 977 6 juin 19:40 F0F148EF8B2A7A35BA48F175F861883BF3F5848E.key
-rw------- 1 max users 361 10 oct. 20:03 FF73871150A205DF1BC63A1F28544C9244749DFB.key
max@host % gpg --list-secret-keys --with-keygrip | grep -C6 F0F148EF8B2A7A35BA48F175F861883BF3F5848E
Keygrip = 3BF18C02C764451AD7CBD6504ED7936E571BB87C
ssb rsa4096 2012-10-01 [E]
Keygrip = 7AD225A04E857C1FEA6D0C687D75848692D56CF5
sec rsa2048 2018-06-06 [SC]
E5FD72F728F94FBF85453FA06C5CF27EBC044A8C
Keygrip = F0F148EF8B2A7A35BA48F175F861883BF3F5848E
uid [ unknown] learnybox
ssb rsa2048 2018-06-06 [E]
Keygrip = 3D60E5ADEDB55BFC10E7F212728C8C17E4D489F7
Content of private-keys-v1.d: https://lists.gnupg.org/pipermail/gnupg-users/2017-February/057625.html