J'ai la clé publique GPG suivante stockée dans un fichier appelé publickey.pub
et codé en ASCII Armor (Radix-64) :
-----BEGIN PGP PUBLIC KEY BLOCK-----
Version: 2.6.3ia
mQCNAzNko/QAAAEEANZ2kpN/oMkz4tqzxvKPZws/XwsD0Y+E5/y7P2DIw4uHS/4N
syQbgkdrZhPBlXDv68DQioHXWsb904qyr7iZB1LC5ItK9MgqlK+Z2mvPqsGbHM8J
+oYib8kf2zJ6HvrYrP7NYB0tN9YYum2ICtx+hIi6aKGXdB1ATA5erwYmu0N9AAUR
tClSYWxmIFMuIEVuZ2Vsc2NoYWxsIDxyc2VAZW5nZWxzY2hhbGwuY29tPokAlQMF
EDNko/QOXq8GJrtDfQEBKVoD/2K/+4pcwhxok+FkuLwC5Pnuh/1oeOYHiKYwx0Z3
p09RLvDtNldr6VD+aL9JltxdPTARzZ8M50UqoF9jMr25GifheFYhilww41OVZA3e
cLXlLgda1+t0vWs3Eg/i2b0arQQDaIq7PeRdjdEDgwnG4xBaqaAqfgxwOXJ+LPWF
hiXZ
=K7lL
-----END PGP PUBLIC KEY BLOCK-----
Si je tape :
$ gpg --with-fingerprint publickey.pub
J'ai l'empreinte digitale de la clé :
Empreinte de la clé = 00 C9 21 8E D1 AB 70 37 DD 67 A2 3A 0A 6F 8D A5
Maintenant, comment GPG fait-il ? Je veux dire, y a-t-il une commande que je peux exécuter sans utiliser gpg
et obtenir toujours la même empreinte digitale ? Avec SSH, par exemple, étant donné une clé publique, je peux faire ce qui suit :
$ cat ~/.ssh/id_rsa.pub | awk '{print $2}' | base64 -D | md5
Et cela retournera le même hachage que :
$ ssh-keygen -l -f ~/.ssh/id_rsa.pub
Je sais que le contenu réel de la clé publique devrait être :
mQCNAzNko/QAAAEEANZ2kpN/oMkz4tqzxvKPZws/XwsD0Y+E5/y7P2DIw4uHS/4N
syQbgkdrZhPBlXDv68DQioHXWsb904qyr7iZB1LC5ItK9MgqlK+Z2mvPqsGbHM8J
+oYib8kf2zJ6HvrYrP7NYB0tN9YYum2ICtx+hIi6aKGXdB1ATA5erwYmu0N9AAUR
tClSYWxmIFMuIEVuZ2Vsc2NoYWxsIDxyc2VAZW5nZWxzY2hhbGwuY29tPokAlQMF
EDNko/QOXq8GJrtDfQEBKVoD/2K/+4pcwhxok+FkuLwC5Pnuh/1oeOYHiKYwx0Z3
p09RLvDtNldr6VD+aL9JltxdPTARzZ8M50UqoF9jMr25GifheFYhilww41OVZA3e
cLXlLgda1+t0vWs3Eg/i2b0arQQDaIq7PeRdjdEDgwnG4xBaqaAqfgxwOXJ+LPWF
hiXZ
Sans le dernier =K7lL
qui fait référence à la somme de contrôle CRC encodée en Base64. Mais si je tape :
$ echo -n "mQCNAzNko/QAAAEEANZ2kpN/oMkz4tqzxvKPZws/XwsD0Y+E5/y7P2DIw4uHS/4N
> syQbgkdrZhPBlXDv68DQioHXWsb904qyr7iZB1LC5ItK9MgqlK+Z2mvPqsGbHM8J
> +oYib8kf2zJ6HvrYrP7NYB0tN9YYum2ICtx+hIi6aKGXdB1ATA5erwYmu0N9AAUR
> tClSYWxmIFMuIEVuZ2Vsc2NoYWxsIDxyc2VAZW5nZWxzY2hhbGwuY29tPokAlQMF
> EDNko/QOXq8GJrtDfQEBKVoD/2K/+4pcwhxok+FkuLwC5Pnuh/1oeOYHiKYwx0Z3
> p09RLvDtNldr6VD+aL9JltxdPTARzZ8M50UqoF9jMr25GifheFYhilww41OVZA3e
> cLXlLgda1+t0vWs3Eg/i2b0arQQDaIq7PeRdjdEDgwnG4xBaqaAqfgxwOXJ+LPWF
> hiXZ" | base64 -D | md5
J'obtiens le résultat suivant :
4697e84969da935454c7f2cdc19aaf08
Ce qui, comme vous pouvez le voir, ne correspond pas 00 C9 21 8E...
Vérifier la RFC 4880 -> https://www.rfc-editor.org/rfc/rfc4880#section-12.2 :
Pour une clé V3, l'identifiant de clé de huit octets est constitué des 64 bits inférieurs de l'identifiant de clé V3.
le modulus public de la clé RSA.L'empreinte digitale d'une clé V3 est formée par le hachage du corps (mais pas de la clé V3). la longueur de deux octets) des MPI qui constituent le matériel de la clé (public, privé, privé).
module n, suivi de l'exposant e) avec MD5. Notez que les deux clés V3
et MD5 sont obsolètes.Une empreinte digitale V4 est le hachage SHA-1 de 160 bits de l'octet 0x99,
suivi de la longueur du paquet de deux octets, suivi de l'ensemble de l'information
Paquet de clés publiques commençant par le champ version. L'ID de la clé est le 64 bits de poids faible de l'empreinte digitale.
Comment cela se traduit-il par une commande en ligne de commande ?
EDIT 1 : J'essaie de faire cela avec pgpdump -i
:
$ pgpdump -i publickey.pub
Old: Public Key Packet(tag 6)(141 bytes)
Ver 3 - old
Public key creation time - Mon Apr 28 17:19:48 MSD 1997
Valid days - 0[0 is forever]
Pub alg - RSA Encrypt or Sign(pub 1)
RSA n(1024 bits) - d6 76 92 93 7f a0 c9 33 e2 da b3 c6 f2 8f 67 0b 3f 5f 0b 03 d1 8f 84 e7 fc bb 3f 60 c8 c3 8b 87 4b fe 0d b3 24 1b 82 47 6b 66 13 c1 95 70 ef eb c0 d0 8a 81 d7 5a c6 fd d3 8a b2 af b8 99 07 52 c2 e4 8b 4a f4 c8 2a 94 af 99 da 6b cf aa c1 9b 1c cf 09 fa 86 22 6f c9 1f db 32 7a 1e fa d8 ac fe cd 60 1d 2d 37 d6 18 ba 6d 88 0a dc 7e 84 88 ba 68 a1 97 74 1d 40 4c 0e 5e af 06 26 bb 43 7d
RSA e(5 bits) - 11
Old: User ID Packet(tag 13)(41 bytes)
User ID - Ralf S. Engelschall <rse@engelschall.com>
Old: Signature Packet(tag 2)(149 bytes)
Ver 3 - old
Hash material(5 bytes):
Sig type - Generic certification of a User ID and Public Key packet(0x10).
Creation time - Mon Apr 28 17:19:48 MSD 1997
Key ID - 0x0E5EAF0626BB437D
Pub alg - RSA Encrypt or Sign(pub 1)
Hash alg - MD5(hash 1)
Hash left 2 bytes - 29 5a
RSA m^d mod n(1023 bits) - 62 bf fb 8a 5c c2 1c 68 93 e1 64 b8 bc 02 e4 f9 ee 87 fd 68 78 e6 07 88 a6 30 c7 46 77 a7 4f 51 2e f0 ed 36 57 6b e9 50 fe 68 bf 49 96 dc 5d 3d 30 11 cd 9f 0c e7 45 2a a0 5f 63 32 bd b9 1a 27 e1 78 56 21 8a 5c 30 e3 53 95 64 0d de 70 b5 e5 2e 07 5a d7 eb 74 bd 6b 37 12 0f e2 d9 bd 1a ad 04 03 68 8a bb 3d e4 5d 8d d1 03 83 09 c6 e3 10 5a a9 a0 2a 7e 0c 70 39 72 7e 2c f5 85 86 25 d9
-> PKCS-1
Comment dois-je extraire le module et l'exposant ? Je suppose que je devrais faire quelque chose avec cette partie de la sortie :
Hash left 2 bytes - 29 5a
RSA m^d mod n(1023 bits) - 62 bf fb 8a 5c c2 1c 68 93 e1 64 b8 bc 02 e4 f9 ee 87 fd 68 78 e6 07 88 a6 30 c7 46 77 a7 4f 51 2e f0 ed 36 57 6b e9 50 fe 68 bf 49 96 dc 5d 3d 30 11 cd 9f 0c e7 45 2a a0 5f 63 32 bd b9 1a 27 e1 78 56 21 8a 5c 30 e3 53 95 64 0d de 70 b5 e5 2e 07 5a d7 eb 74 bd 6b 37 12 0f e2 d9 bd 1a ad 04 03 68 8a bb 3d e4 5d 8d d1 03 83 09 c6 e3 10 5a a9 a0 2a 7e 0c 70 39 72 7e 2c f5 85 86 25 d9
J'ai essayé de faire écho aux valeurs binaires de ces chiffres hexadécimaux :
29 5a
(hachage des 2 octets restants) concaténé avec : 62 bf fb 8a 5c c2 1c 68 93 e1 64 b8 bc 02 e4 f9 ee 87 fd 68 78 e6 07 88 a6 30 c7 46 77 a7 4f 51 2e f0 ed 36 57 6b e9 50 fe 68 bf 49 96 dc 5d 3d 30 11 cd 9f 0c e7 45 2a a0 5f 63 32 bd b9 1a 27 e1 78 56 21 8a 5c 30 e3 53 95 64 0d de 70 b5 e5 2e 07 5a d7 eb 74 bd 6b 37 12 0f e2 d9 bd 1a ad 04 03 68 8a bb 3d e4 5d 8d d1 03 83 09 c6 e3 10 5a a9 a0 2a 7e 0c 70 39 72 7e 2c f5 85 86 25 d9
Et la commande à laquelle j'ai abouti était :
$ echo -ne "\x29\x5a\x62\xbf\xfb\x8a\x5c\xc2\x1c\x68\x93\xe1\x64\xb8\xbc\x02\xe4\xf9\xee\x87\xfd\x68\x78\xe6\x07\x88\xa6\x30\xc7\x46\x77\xa7\x4f\x51\x2e\xf0\xed\x36\x57\x6b\xe9\x50\xfe\x68\xbf\x49\x96\xdc\x5d\x3d\x30\x11\xcd\x9f\x0c\xe7\x45\x2a\xa0\x5f\x63\x32\xbd\xb9\x1a\x27\xe1\x78\x56\x21\x8a\x5c\x30\xe3\x53\x95\x64\x0d\xde\x70\xb5\xe5\x2e\x07\x5a\xd7\xeb\x74\xbd\x6b\x37\x12\x0f\xe2\xd9\xbd\x1a\xad\x04\x03\x68\x8a\xbb\x3d\xe4\x5d\x8d\xd1\x03\x83\x09\xc6\xe3\x10\x5a\xa9\xa0\x2a\x7e\x0c\x70\x39\x72\x7e\x2c\xf5\x85\x86\x25\xd9" | md5
Ce qui devrait produire les données binaires de ces chiffres hexadécimaux, puis calculer le hachage MD5 sur ces données binaires, mais le hachage que j'obtiens est toujours différent :
6f09f2ac5c5af1c6dd3833e584387103
Je sais que je m'y prends mal, mais je n'ai pas trouvé d'informations sur la façon d'interpréter les données de l'enquête. pgpdump
correctement et quelles parties de ce que je dois concaténer et ensuite hacher...
EDIT : Grâce à Jens Erat, avec ce petit "geeking des empreintes digitales d'OpenPGP" je peux conclure que :
Pour Clés V3 RSA 1024 bit Les clés sont hachées avec MD5 l'empreinte digitale est calculée par rapport à 129 octets composés de l 128 octets de l RSA n MPI (qui commence à l'offset de l'octet 14 (à condition que le premier octet soit à l'offset 1 ) de la clé publique OpenPGP brute exportée avec gpg --export $UID
) concaténée avec 1 qui est l'octet à l'offset 144 et donc d'omettre le 2 longueur octets à l'offset 142 y 143 comme le dit la RFC 4880.
La commande suivante calcule l'empreinte digitale en utilisant les données GPG brutes et :
gpg --export $UID | xxd -p | tr -d '\n ' | tail \
-c +27 | cut -c -256,261-262 | sed -e 's/[0-9a-fA-F]\{2\}/\\\\x&/g' | while read TMP; do \
echo -ne $TMP; done | md5 | sed -e 's/[0-9a-f]\{2\}/ &/g' | \
awk '{print "\n MD5 fingerprint:"toupper($0)"\n"}'
Où $UID est l'UID du détenteur de la clé.
Pour les clés publiques OpenPGP V4 RSA, l'histoire est différente :
Pour les clés publiques RSA de 2048 bits, l'empreinte digitale est obtenue en hachant les 272 premiers octets des données brutes de la clé OpenPGP avec SHA1 :
gpg --export $UID | head -c 272 | shasum | grep -Eo "[0-9a-f]+" | sed -e 's/[0-9a-f]\{4\}/ &/g' | \
awk '{print "\n RSA 2048 bit SHA1 fingerprint:"toupper($0)"\n"}'
Pour les clés publiques RSA de 4096 bits, l'empreinte digitale est obtenue en hachant les 528 premiers octets des données brutes de la clé OpenPGP avec SHA1 :
gpg --export $UID | head -c 528 | shasum | \
grep -Eo "[0-9a-f]+" | sed -e 's/[0-9a-f]\{4\}/ &/g' | \
awk '{print "\n RSA 4096 SHA1 fingerprint:"toupper($0)"\n"}'
Cela devrait suffire. Quoi qu'il en soit, en utilisant gpgsplit
avec les touches V4 semble être plus portable.