How to display gpg key details without importing it?
Asked Answered
C

9

214

I have a copy of the postgresql apt repository gpg key and would like to view the details of the gpg key as it comes in the file. Is this possible without importing it into a key ring?

Cretan answered 3/3, 2014 at 1:10 Comment(0)
L
235

There are several detail levels you can get when looking at OpenPGP key data: a basic summary, a machine-readable output of this summary or a detailed (and very technical) list of the individual OpenPGP packets.

Basic Key Information

For a brief peak at an OpenPGP key file, you can simply pass the filename as parameter or pipe in the key data through STDIN. If no command is passed, GnuPG tries to guess what you want to do -- and for key data, this is printing a summary on the key:

$ gpg a4ff2279.asc
gpg: WARNING: no command supplied.  Trying to guess what you mean ...
pub   rsa8192 2012-12-25 [SC]
      0D69E11F12BDBA077B3726AB4E1F799AA4FF2279
uid           Jens Erat (born 1988-01-19 in Stuttgart, Germany)
uid           Jens Erat <[email protected]>
uid           Jens Erat <[email protected]>
uid           Jens Erat <[email protected]>
uid           Jens Erat <[email protected]>
uid           [jpeg image of size 12899]
sub   rsa4096 2012-12-26 [E] [revoked: 2014-03-26]
sub   rsa4096 2012-12-26 [S] [revoked: 2014-03-26]
sub   rsa2048 2013-01-23 [S] [expires: 2023-01-21]
sub   rsa2048 2013-01-23 [E] [expires: 2023-01-21]
sub   rsa4096 2014-03-26 [S] [expires: 2020-09-03]
sub   rsa4096 2014-03-26 [E] [expires: 2020-09-03]
sub   rsa4096 2014-11-22 [A] [revoked: 2016-03-01]
sub   rsa4096 2016-02-24 [A] [expires: 2020-02-23]

By setting --keyid-format 0xlong, long key IDs are printed instead of the insecure short key IDs:

$ gpg a4ff2279.asc                                                                 
gpg: WARNING: no command supplied.  Trying to guess what you mean ...
pub   rsa8192/0x4E1F799AA4FF2279 2012-12-25 [SC]
      0D69E11F12BDBA077B3726AB4E1F799AA4FF2279
uid                             Jens Erat (born 1988-01-19 in Stuttgart, Germany)
uid                             Jens Erat <[email protected]>
uid                             Jens Erat <[email protected]>
uid                             Jens Erat <[email protected]>
uid                             Jens Erat <[email protected]>
uid                             [jpeg image of size 12899]
sub   rsa4096/0x0F3ED8E6759A536E 2012-12-26 [E] [revoked: 2014-03-26]
sub   rsa4096/0x2D6761A7CC85941A 2012-12-26 [S] [revoked: 2014-03-26]
sub   rsa2048/0x9FF7E53ACB4BD3EE 2013-01-23 [S] [expires: 2023-01-21]
sub   rsa2048/0x5C88F5D83E2554DF 2013-01-23 [E] [expires: 2023-01-21]
sub   rsa4096/0x8E78E44DFB1B55E9 2014-03-26 [S] [expires: 2020-09-03]
sub   rsa4096/0xCC73B287A4388025 2014-03-26 [E] [expires: 2020-09-03]
sub   rsa4096/0x382D23D4C9773A5C 2014-11-22 [A] [revoked: 2016-03-01]
sub   rsa4096/0xFF37A70EDCBB4926 2016-02-24 [A] [expires: 2020-02-23]
pub   rsa1024/0x7F60B22EA4FF2279 2014-06-16 [SCEA] [revoked: 2016-08-16]

Providing -v or -vv will even add some more information. I prefer printing the package details in this case, though (see below).

Machine-Readable Output

GnuPG also has a colon-separated output format, which is easily parsable and has a stable format. The format is documented in GnuPG doc/DETAILS file. The option to receive this format is --with-colons.

$ gpg --with-colons a4ff2279.asc
gpg: WARNING: no command supplied.  Trying to guess what you mean ...
pub:-:8192:1:4E1F799AA4FF2279:1356475387:::-:
uid:::::::::Jens Erat (born 1988-01-19 in Stuttgart, Germany):
uid:::::::::Jens Erat <[email protected]>:
uid:::::::::Jens Erat <[email protected]>:
uid:::::::::Jens Erat <[email protected]>:
uid:::::::::Jens Erat <[email protected]>:
uat:::::::::1 12921:
sub:-:4096:1:0F3ED8E6759A536E:1356517233:1482747633:::
sub:-:4096:1:2D6761A7CC85941A:1356517456:1482747856:::
sub:-:2048:1:9FF7E53ACB4BD3EE:1358985314:1674345314:::
sub:-:2048:1:5C88F5D83E2554DF:1358985467:1674345467:::
sub:-:4096:1:8E78E44DFB1B55E9:1395870592:1599164118:::
sub:-:4096:1:CC73B287A4388025:1395870720:1599164118:::
sub:-:4096:1:382D23D4C9773A5C:1416680427:1479752427:::
sub:-:4096:1:FF37A70EDCBB4926:1456322829:1582466829:::

Since GnuPG 2.1.23, the gpg: WARNING: no command supplied. Trying to guess what you mean ... warning can be omitted by using the --import-options show-only option together with the --import command (this also works without --with-colons, of course):

$ gpg --with-colons --import-options show-only --import a4ff2279
[snip]

For older versions: the warning message is printed on STDERR, so you could just read STDIN to split apart the key information from the warning.

Technical Details: Listing OpenPGP Packets

Without installing any further packages, you can use gpg --list-packets [file] to view information on the OpenPGP packets contained in the file.

$ gpg --list-packets a4ff2279.asc
:public key packet:
    version 4, algo 1, created 1356475387, expires 0
    pkey[0]: [8192 bits]
    pkey[1]: [17 bits]
    keyid: 4E1F799AA4FF2279
:user ID packet: "Jens Erat (born 1988-01-19 in Stuttgart, Germany)"
:signature packet: algo 1, keyid 4E1F799AA4FF2279
    version 4, created 1356516623, md5len 0, sigclass 0x13
    digest algo 2, begin of digest 18 46
    hashed subpkt 27 len 1 (key flags: 03)
[snip]

The pgpdump [file] tool works similar to gpg --list-packets and provides a similar output, but resolves all those algorithm identifiers to readable representations. It is available for probably all relevant distributions (on Debian derivatives, the package is called pgpdump like the tool itself).

$ pgpdump a4ff2279.asc
Old: Public Key Packet(tag 6)(1037 bytes)
    Ver 4 - new
    Public key creation time - Tue Dec 25 23:43:07 CET 2012
    Pub alg - RSA Encrypt or Sign(pub 1)
    RSA n(8192 bits) - ...
    RSA e(17 bits) - ...
Old: User ID Packet(tag 13)(49 bytes)
    User ID - Jens Erat (born 1988-01-19 in Stuttgart, Germany)
Old: Signature Packet(tag 2)(1083 bytes)
    Ver 4 - new
    Sig type - Positive certification of a User ID and Public Key packet(0x13).
    Pub alg - RSA Encrypt or Sign(pub 1)
    Hash alg - SHA1(hash 2)
    Hashed Sub: key flags(sub 27)(1 bytes)
[snip]
Leonelleonelle answered 3/3, 2014 at 13:11 Comment(7)
Thanks. I just used "gpg --list-keys path-to-key-file" and got what I wanted to see: ... hashed subpkt 2 len 4 (sig created 2013-02-24) hashed subpkt 9 len 4 (key expires after 4y134d23h24m) ... and pgpdump makes the output a little more readable.Cretan
@AmosShapira Are you sure? That command doesn't work for me at all. Maybe you meant --list-packets ?Preachment
@JonathanCross Indeed, the described output sounds like --list-packets.Leonelleonelle
How to get rid of this ugly WARNING: no command supplied to stderr? (This thwarts using gpg in scripts properly. When it comes to crypto the only safe way is to treat any output to stderr as fatal error. Only this way you will be prepared when new important weaknesses are discovered which only print to stderr).Nisbet
I'm not aware there is an easy way around. You can still use the key file as keyring though and then run --list-keys, something like gpg --no-default-keyring --keyring=/tmp/<keyfile> --list-keys. Or simply discard the warning message, there is a bunch of options to filter stderr in (ba)sh scripts.Leonelleonelle
An alternative to --import-options show-only --import is --show-keys, which appears to have been added around early 2019 [edit: ~2.2.12-13 area, without delving into changelogs]. (also mentioned in @Pawel 's answer )Fullfaced
--show-keys should be included in this answer, since that's basically what happens when you have gpg try to "guess what you mean"Certitude
H
70

To verify and list the fingerprint of the key (without importing it into the keyring first), type

gpg --show-keys --with-fingerprint <filename>

Edit: on Ubuntu 18.04 (gpg 2.2.4) the fingerprint isn't show with the above command. Use the --with-subkey-fingerprint option instead

gpg --show-keys --with-subkey-fingerprint <filename>
Hugues answered 8/3, 2016 at 16:48 Comment(6)
This should be the accepted answer imo. I agree with the comment-posted-as-answer by @Skyr.Firebrick
ACK, this is very good, doesn't require local personal keyring etc. does display the key name... works best.Theurich
For some unknown/undocumented reason gpg --with-fingerprint suppresses printing fingerprints at my side. Ubuntu 18.04 gpg (GnuPG) 2.1.18Nisbet
Same thing is happening for me too @Tino, did you find any additional info about why?Paleobiology
@Nisbet and @Paleobiology Updated the answer with --with-subkey-fingerprint info that should work on Ubuntu 18.04Hugues
On Arch, gpg --show-keys <keyfile> produces the same output, but without the "WARNING..." mentioned by @JensErat.Balalaika
N
34

I seem to be able to get along with simply:

$gpg <path_to_file>

Which outputs like this:

$ gpg /tmp/keys/something.asc 
  pub  1024D/560C6C26 2014-11-26 Something <[email protected]>
  sub  2048g/0C1ACCA6 2014-11-26

The op didn't specify in particular what key info is relevant. This output is all I care about.

Narda answered 4/12, 2014 at 17:53 Comment(2)
This will create ~/.gnupg/pubring.kbx. So the method is intrusive (((Aspiration
@Aspiration You're correct! To avoid this, better to do gpg <filename> 2>&1Floss
W
10

The option --list-packets parses pgp data from a file and outputs its structure - in a very technical way, though. When parsing a public key, you can easily extract the user ids and the key ids of the signatures.

Be wary that this command only parses the data format, it does no validation of signatures or similar things.

Wrestling answered 3/3, 2014 at 13:0 Comment(1)
For a signature .asc file (not a public key .asc file), using gpg 2.2.27, gpg --list-packets some-signature.asc seems to be the only way to extract the contained fingerprint.Badminton
S
10

You may also use --keyid-format switch to show short or long key ID:

$ gpg2 -n --with-fingerprint --keyid-format=short --show-keys <filename>

which outputs like this (example from PostgreSQL CentOS repo key):

pub   dsa1024/442DF0F8 2008-01-08 [SCA]                                                                       │
      Key fingerprint = 68C9 E2B9 1A37 D136 FE74  D176 1F16 D2E1 442D F0F8                                    │              honor-keyserver-url
uid                    PostgreSQL RPM Building Project <[email protected]>                      │                     When  using --refresh-keys, if the key in question has a preferred keyserver URL, then use that
sub   elg2048/D43F1AF8 2008-01-08 [E]
Satinet answered 16/7, 2019 at 8:51 Comment(0)
K
5

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 --import <key.asc

also works in all 3 versions, but in GPG 1.4.16 it prints only a short (4 bytes, 8 hex digits) key ID, so it's less secure to identify keys.

Some 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.

Korten answered 30/4, 2020 at 11:11 Comment(0)
B
4

For newer versions of gngpg version 2.2.8 and above:

If you want only want to get the short or long fingerprint of the key without importing the key and without redirecting stderr to stdout 2>&1:
(i.e. when you have scripts verifying the fingerprint before proceeding like with ansible)


I have included a way with --with-colons and one without depending on your scripting preferences.

To get short format key ID

  • short key id format (using --show-keys and --with-colons):
gpg --show-keys --with-colons keyfile.key | awk -F':' '$1=="pub"{print $5}'

  • short key id format (using --list-packets):
gpg --list-packets keyfile.key | awk '$1=="keyid:"{print$2}'

To get long format key ID

  • long key id format (using --show-keys and --with-colons):
gpg --show-keys --with-colons keyfile.key | awk -F':' '$1=="fpr"{print $10}'
  • long key id format (using --show-keys):
gpg --show-keys keyfile.key | sed -nr 's/^([ ]+)([0-9A-Z]{40}$)/\2/p'

Bay answered 15/1, 2023 at 19:54 Comment(0)
R
3

When I stumbled up on this answer I was looking for a way to get an output that is easy to parse. For me the option --with-colons did the trick:

$ gpg --with-colons file
sec::4096:1:AAAAAAAAAAAAAAAA:YYYY-MM-DD::::Name (comment) email
ssb::4096:1:BBBBBBBBBBBBBBBB:YYYY-MM-DD::::

Documentation can be found here.

Remanent answered 10/5, 2017 at 13:20 Comment(1)
How do you get that nice YYYY-MM-DD output? I can't reproduce that with gpg2.x and --with-colons.Bowfin
D
1

pgpdump (https://www.lirnberger.com/tools/pgpdump/) is a tool that you can use to inspect pgp blocks.

It is not user friendly, and fairly technical, however,

  • it parses public or private keys (without warning)
  • it does not modify any keyring (sometimes it is not so clear what gpg does behind the hood, in my experience)
  • it prints all packets, specifically userid's packets which shows the various text data about the keys.
pgpdump -p test.asc 
New: Secret Key Packet(tag 5)(920 bytes)
    Ver 4 - new
    Public key creation time - Fri May 24 00:33:48 CEST 2019
    Pub alg - RSA Encrypt or Sign(pub 1)
    RSA n(2048 bits) - ...
    RSA e(17 bits) - ...
    RSA d(2048 bits) - ...
    RSA p(1024 bits) - ...
    RSA q(1024 bits) - ...
    RSA u(1020 bits) - ...
    Checksum - 49 2f 
New: User ID Packet(tag 13)(18 bytes)
    User ID - test (test) <tset>                        
New: Signature Packet(tag 2)(287 bytes)
    Ver 4 - new
    Sig type - Positive certification of a User ID and Public Key packet(0x13).
    Pub alg - RSA Encrypt or Sign(pub 1)
    Hash alg - SHA256(hash 8)
    Hashed Sub: signature creation time(sub 2)(4 bytes)
        Time - Fri May 24 00:33:49 CEST 2019
    Hashed Sub: issuer key ID(sub 16)(8 bytes)
        Key ID - 0x396D5E4A2E92865F
    Hashed Sub: key flags(sub 27)(1 bytes)
        Flag - This key may be used to certify other keys
        Flag - This key may be used to sign data
    Hash left 2 bytes - 74 7a 
    RSA m^d mod n(2048 bits) - ...
        -> PKCS-1

unfortunately it does not read stdin : /

Derosa answered 23/5, 2019 at 22:49 Comment(1)
My pgpdump reads stdin. E.g., curl -s https://www.theguardian.com/pgp/PublicKeys/Guardian%20Application-Security.pub.txt | pgpdump works fine.Sinkhole

© 2022 - 2024 — McMap. All rights reserved.