21

Is there a way via an CLI tool or some kind of API to extract the PGP key ID from the PGP public key block?

I found the hexa value of the key in the binary file, but I guess the position is based on the key kind/size.

Basically, I have the base64 formatted public key and I would like to retrieve the key ID from it, without importing it with GnuPG.

12

RFC 4880 on OpenPGP message format talks about how to calculate key ID from public key.

Excerpts from section 12.2:

For a V3 key, the eight-octet Key ID consists of the low 64 bits of the public modulus of the RSA key.

And for V4 keys:

A V4 fingerprint is the 160-bit SHA-1 hash of the octet 0x99, followed by the two-octet packet length, followed by the entire Public-Key packet starting with the version field. The Key ID is the low-order 64 bits of the fingerprint.

You can easily parse the last 64 bits from the base64 encoded public keys, which is the key ID for the corresponding public key.

| improve this answer | |
  • 3
    could you please elaborate more on "easily parse the last 64 bits..."? I generated a pgp key (Got its MPI in base64 format. Is it what is meant by public key?), copy-n-pasted it to here, for example, and counted last 8 bytes in hex representation. Is that correct? – rightaway717 Mar 27 '15 at 14:50
18

You can use gpg --dry-run to prevent changes.

Following line will print the key id in its output (can be modified using the usual modifiers like --with-colons for further processing). A4FF2279 is the key ID in here.

$ gpg --dry-run --import pubkey.asc
gpg: key A4FF2279: public key "[User ID not found]" imported
gpg: Total number processed: 1
gpg:               imported: 1  (RSA: 1)
gpg: no ultimately trusted keys found

Just tried it, the key did not get stored to my keychain, but the key ID was printed. But watch out with --dry-run, the man page has a warning:

   --dry-run
         Don't make any changes (this is not completely implemented).

A more in-depth discussion of multiple variants for human-readable, machine-readable and very technical output for different versions of GnuPG is found in the Stack Overflow question How to display gpg key details without importing it?. All of them will also present the key ID.

| improve this answer | |
  • 1
    Would be nice, if you could update your answer mentioning the --import --import-options show-only, which seams to be the cleanest solution (regarding the not completely implemented problem), like you already did here: How to display gpg key details without importing it? – Murmel Nov 5 '18 at 14:19
  • Instead of duplicating the whole answer I went for a hotlink. – Jens Erat Nov 24 '18 at 7:00
  • 2
    I had to add --verbose to have it print the ID/email. (First I also had to create the .gpg directory in $HOME - not sure if that's a WSL/Ubuntu quirk or what.) – sequentiallee Dec 29 '19 at 14:52
  • @Murmel: gpg --import --import-options show only doesn't work with GPG 1.416. – pts Apr 30 at 10:43
6

From the gpg manual (gpg (GnuPG) 2.2.11):

--show-keys

This commands takes OpenPGP keys as input and prints information about them in the same way the command --list-keys does for locally stored key. In addition the list options show-unusable-uids, show-unusable-subkeys, show-notations and show-policy-urls are also enabled. As usual for automated processing, this command should be combined with the option --with-colons.

For instance:

$ gpg --show-keys docker-ce.gpg pub rsa4096 2017-02-22 [SCEA] 9DC858229FC7DD38854AE2D88D81803C0EBFCD88 uid Docker Release (CE deb) <docker@docker.com> sub rsa4096 2017-02-22 [S]

where 9DC858229FC7DD38854AE2D88D81803C0EBFCD88 is the key id.

| improve this answer | |
  • I didn't downvote, but I suspect it's getting them because this is very short. Can you provide some explanation of what this command is doing? – Mike Ounsworth Dec 17 '18 at 21:49
  • Thanks for the advise @MikeOunsworth. I hope my new answer is more appropiate. – Traz Dec 19 '18 at 9:52
  • Earlier versions of GPG, e.g. 2.1.18 don't have --show-keys. – pts Apr 30 at 10:37
4

gpg --with-fingerprint GPG-KEY-filename-that-you-downloaded-from-internet

For example :

wget https://artifacts.elastic.co/GPG-KEY-elasticsearch

gpg --with-fingerprint GPG-KEY-elasticsearch

| improve this answer | |
  • 3
    can you expand this answer with what the command argument does and the output from that key? – schroeder Nov 9 '17 at 12:15
  • 2
    command missing – chefarov Mar 26 '18 at 14:28
  • I.e.: If you like to validate a downloaded Oracle Java RPM package, you may check the package via rpm -qip <RPM> | grep -i signature and check the key via gpg --with-fingerprint RPM-GPG-KEY-ORACLE. You will find as output Signature : RSA/SHA256, Sat 06 Oct 2018 03:29:42 PM WEST, Key ID 72f97b74ec551f03 and pub 2048R/EC551F03 2010-07-01 Oracle OSS group (Open Source Software group) <build@oss.oracle.com> Key fingerprint = 4214 4123 FECF C55B 9086 313D 72F9 7B74 EC55 1F03. As you can see, Key ID 72f9 7b74 ec55 1f03 fits to the fingerprint. – U880D Dec 3 '18 at 12:54
  • gpg --with-fingerprint FILENAME works with GPG 1.4.16, but it doesn't work with GPG 2.1.18. – pts Apr 30 at 10:41
3

To avoid the "not completely implemented" issue mentioned in Jens Erat's answer, use gpg --homedir on a temporary directory. You may need to modify the mktemp command based on your platform:

gpg --homedir $( mktemp -d -t '' ) --import /tmp/somekey.asc
| improve this answer | |
1

After the public key has been imported

pgp --import PublicKeyToImport.asc

run

pgp --list-userids

to determine the key or User ID to be used with --encrypt.

Alg  Type Size/Type Flags   Key ID     User ID
---- ---- --------- ------- ---------- -------
| improve this answer | |
  • The question explicitly asks for a solution without importing the key. This answer doesn't answer the question. – pts Apr 30 at 10:38
1

To get the key IDs (8 bytes, 16 hex digits), this is the command which worked for me in GPG 1.4.16, 2.1.18 and 2.2.19:

gpg --list-packets <key.asc | awk '$1=="keyid:"{print$2}'

To get some more information (in addition to the key ID):

gpg --list-packets <key.asc

To get even more information:

gpg --list-packets -vvv --debug 0x2 <key.asc

The command

gpg --dry-run --keyid-format long --import <key.asc

also works in all 3 versions, but in GPG 2.1.18 it prints the key ID of the main key only (and not the subkeys), and in 1.4.16 it prints both the main keys and the subkeys.

Commands in other answers (e.g. gpg --show-keys, gpg --with-fingerprint, gpg --import --import-options show-only) don't work in some of the 3 GPG versions above, thus they are not portable when targeting multiple versions of GPG.

| improve this answer | |
  • 1
    gpg 1 defaults to short keyid but you can specify (or configure in gpg.conf) --keyid-format=long – dave_thompson_085 May 1 at 1:50
  • @dave_thompson_085: Thank you for proposing --keyid-format long. I've added it to my answer. However. I strill don't recommend using gpg --dry-run --import because of inconsistencies in subkey key ID reporting among GPG versions. I've also added this to my answer. – pts May 1 at 22:28

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.