202

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?

Jens Erat
  • 37,523
  • 16
  • 80
  • 96
Capt. Crunch
  • 4,490
  • 6
  • 32
  • 38

9 Answers9

223

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 <jens.erat@fsfe.org>
uid           Jens Erat <jens.erat@uni-konstanz.de>
uid           Jens Erat <jabber@jenserat.de>
uid           Jens Erat <email@jenserat.de>
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 <jens.erat@fsfe.org>
uid                             Jens Erat <jens.erat@uni-konstanz.de>
uid                             Jens Erat <jabber@jenserat.de>
uid                             Jens Erat <email@jenserat.de>
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 <jens.erat@fsfe.org>:
uid:::::::::Jens Erat <jens.erat@uni-konstanz.de>:
uid:::::::::Jens Erat <jabber@jenserat.de>:
uid:::::::::Jens Erat <email@jenserat.de>:
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]
Jens Erat
  • 37,523
  • 16
  • 80
  • 96
  • 2
    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. – Capt. Crunch Mar 05 '14 at 03:40
  • @AmosShapira Are you sure? That command doesn't work for me at all. Maybe you meant `--list-packets` ? – Jonathan Cross Dec 01 '18 at 16:08
  • 1
    @JonathanCross Indeed, the described output sounds like `--list-packets`. – Jens Erat Dec 02 '18 at 19:54
  • 2
    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). – Tino Mar 24 '19 at 18:39
  • 1
    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/ --list-keys`. Or simply discard the warning message, there is [a bunch of options to filter stderr in (ba)sh scripts](https://stackoverflow.com/q/3618078/695343). – Jens Erat Mar 24 '19 at 21:08
  • 7
    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](https://stackoverflow.com/a/57053506/237216) ) – mjbnz Feb 09 '21 at 00:58
  • `--show-keys` should be included in this answer, since that's basically what happens when you have `gpg` try to "guess what you mean" – stewSquared Nov 05 '21 at 00:52
65

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>
gavenkoa
  • 45,285
  • 19
  • 251
  • 303
Ronny Andersson
  • 1,558
  • 13
  • 12
  • 6
    This should be the accepted answer imo. I agree with the [comment-posted-as-answer](https://stackoverflow.com/a/22147506/1254292) by @Skyr. – gertvdijk Nov 03 '16 at 09:30
  • 3
    ACK, this is very good, doesn't require local personal keyring etc. does display the key name... works best. – Florian Heigl Apr 30 '17 at 16:22
  • 1
    For some unknown/undocumented reason `gpg --with-fingerprint` suppresses printing fingerprints at my side. Ubuntu 18.04 `gpg (GnuPG) 2.1.18` – Tino Mar 24 '19 at 18:42
  • Same thing is happening for me too @Tino, did you find any additional info about why? – kjones Apr 12 '19 at 02:10
  • @Tino and @kjones Updated the answer with `--with-subkey-fingerprint` info that should work on Ubuntu 18.04 – Ronny Andersson Jul 29 '19 at 15:37
  • 1
    On Arch, `gpg --show-keys ` produces the same output, but without the "WARNING..." mentioned by @JensErat. – joharr Oct 23 '21 at 06:31
33

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 <something@none.org>
  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.

Therealstubot
  • 757
  • 1
  • 7
  • 16
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 <pgsqlrpms-hackers@pgfoundry.org>                      │                     When  using --refresh-keys, if the key in question has a preferred keyserver URL, then use that
sub   elg2048/D43F1AF8 2008-01-08 [E]
Paweł
  • 101
  • 1
  • 6
9

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.

Skyr
  • 980
  • 7
  • 12
  • 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. – Abdull Mar 22 '23 at 23:11
4

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.

pts
  • 80,836
  • 20
  • 110
  • 183
3

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'

justsomeguy
  • 513
  • 4
  • 11
2

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.

Heye
  • 603
  • 6
  • 14
  • 1
    How do you get that nice YYYY-MM-DD output? I can't reproduce that with gpg2.x and --with-colons. – MKesper Apr 02 '19 at 12:03
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 : /

  • My `pgpdump` reads `stdin`. E.g., `curl -s https://www.theguardian.com/pgp/PublicKeys/Guardian%20Application-Security.pub.txt | pgpdump` works fine. – rickhg12hs Mar 07 '20 at 21:32