41

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.

6 Answers 6

15

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.

1
  • 5
    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? Mar 27, 2015 at 14:50
27

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.

4
  • 2
    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, 2018 at 14:19
  • Instead of duplicating the whole answer I went for a hotlink.
    – Jens Erat
    Nov 24, 2018 at 7:00
  • 4
    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.) Dec 29, 2019 at 14:52
  • @Murmel: gpg --import --import-options show only doesn't work with GPG 1.416.
    – pts
    Apr 30, 2020 at 10:43
23

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) <[email protected]>
sub   rsa4096 2017-02-22 [S]

where 9DC858229FC7DD38854AE2D88D81803C0EBFCD88 is the key id.

1
  • 2
    Earlier versions of GPG, e.g. 2.1.18 don't have --show-keys.
    – pts
    Apr 30, 2020 at 10:37
5
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
4
  • 4
    can you expand this answer with what the command argument does and the output from that key?
    – schroeder
    Nov 9, 2017 at 12:15
  • 2
    command missing
    – chefarov
    Mar 26, 2018 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) <[email protected]> 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, 2018 at 12:54
  • 1
    gpg --with-fingerprint FILENAME works with GPG 1.4.16, but it doesn't work with GPG 2.1.18.
    – pts
    Apr 30, 2020 at 10:41
3

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.

2
  • 1
    gpg 1 defaults to short keyid but you can specify (or configure in gpg.conf) --keyid-format=long May 1, 2020 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, 2020 at 22:28
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
---- ---- --------- ------- ---------- -------
1
  • 1
    The question explicitly asks for a solution without importing the key. This answer doesn't answer the question.
    – pts
    Apr 30, 2020 at 10:38

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .