15

I have a file secret.asc containing an ASCII-armored (i.e., plain text and starts with -----BEGIN PGP PRIVATE KEY BLOCK-----) PGP/GPG secret/private key, and I would like to know its 40-character key fingerprint without importing it into my GPG keyring. Unfortunately, not a single command I've tried has surrendered that information to me.

What I've Tried

The following failed attempts were run on Ubuntu Xenial 16.04.5 with gpg version 1.4.20 and gpg2 version 2.1.11. The key in question was created solely for experimentation purposes and won't be used in anything, so I don't care if the output reveals too much about it.

$ gpg --with-fingerprint secret.asc sec 2048R/161722B3 2018-09-12 uid Testing <[email protected]> 

Short key ID only, no fingerprint.

$ gpg2 --with-fingerprint secret.asc gpg: DBG: FIXME: merging secret key blocks is not anymore available gpg: DBG: FIXME: No way to print secret key packets here 

Error.

$ gpg --with-fingerprint --no-default-keyring --secret-keyring ./secret.asc --list-secret-keys gpg: [don't know]: invalid packet (ctb=2d) gpg: keydb_search_first failed: invalid packet 

Error.

$ gpg2 --with-fingerprint --no-default-keyring --secret-keyring ./secret.asc --list-secret-keys /home/jwodder/.gnupg/pubring.gpg -------------------------------- ... 

This lists the secret keys in my keyring for some reason.

$ gpg --dry-run --import -vvvv secret.asc gpg: using character set `utf-8' gpg: armor: BEGIN PGP PRIVATE KEY BLOCK gpg: armor header: Version: GnuPG v1 :secret key packet: version 4, algo 1, created 1536783228, expires 0 skey[0]: [2048 bits] skey[1]: [17 bits] skey[2]: [2047 bits] skey[3]: [1024 bits] skey[4]: [1024 bits] skey[5]: [1021 bits] checksum: 386f keyid: 07C0845B161722B3 :signature packet: algo 1, keyid 07C0845B161722B3 version 4, created 1536783228, md5len 0, sigclass 0x1f digest algo 2, begin of digest b6 12 hashed subpkt 2 len 4 (sig created 2018-09-12) hashed subpkt 12 len 22 (revocation key: c=80 a=1 f=9F3C2033494B382BEF691BB403BB6744793721A3) hashed subpkt 7 len 1 (not revocable) subpkt 16 len 8 (issuer key ID 07C0845B161722B3) data: [2048 bits] :user ID packet: "Testing <[email protected]>" :signature packet: algo 1, keyid 07C0845B161722B3 version 4, created 1536783228, md5len 0, sigclass 0x13 digest algo 2, begin of digest 33 ee hashed subpkt 2 len 4 (sig created 2018-09-12) hashed subpkt 27 len 1 (key flags: 03) hashed subpkt 9 len 4 (key expires after 32d3h46m) hashed subpkt 11 len 5 (pref-sym-algos: 9 8 7 3 2) hashed subpkt 21 len 5 (pref-hash-algos: 8 2 9 10 11) hashed subpkt 22 len 3 (pref-zip-algos: 2 3 1) hashed subpkt 30 len 1 (features: 01) hashed subpkt 23 len 1 (key server preferences: 80) subpkt 16 len 8 (issuer key ID 07C0845B161722B3) data: [2046 bits] gpg: sec 2048R/161722B3 2018-09-12 Testing <[email protected]> gpg: key 161722B3: secret key imported gpg: pub 2048R/161722B3 2018-09-12 Testing <[email protected]> gpg: writing to `/home/jwodder/.gnupg/pubring.gpg' gpg: using PGP trust model gpg: key 793721A3: accepted as trusted key gpg: key 161722B3: public key "[User ID not found]" imported gpg: Total number processed: 1 gpg: imported: 1 (RSA: 1) gpg: secret keys read: 1 gpg: secret keys imported: 1 

The only fingerprint to be found is that of the revocation key.

$ gpg2 --dry-run --import -vvvv secret.asc 

Same output as above.

$ gpg --list-packets secret.asc $ gpg2 --list-packets secret.asc 

Basically the same output as the --dry-run --import -vvvv commands, only without the gpg: lines.

3
  • I wasn't able to get it using GnuPG 2 either -- but using the old-stable GnupG 1.4 gpg1 --no-default-keyring --secret-keyring /tmp/a4ff2279.asc.gpg --with-fingerprint --list-secret-keys works out as expected. Seems like a mix of recent versions of GnupG merging the secret keyring into the public keyring (--secret-keyring ... is just ignored) and some weird behavior when listing keys where this change was forgotten. Might be a bug report candidate. Commented Sep 12, 2018 at 21:34
  • @JensErat: That's my attempt #3; it just gives me an error. What version of gpg are you using? Commented Sep 12, 2018 at 21:40
  • 1
    I forgot one minor but relevant detail: I dearmored the key first (gpg --dearmor). Was not able to get along with the armored copy, either. The ctd=2d error indicates issues with an unexpected - character -- probably the one starting or ending the key. Commented Sep 13, 2018 at 19:10

3 Answers 3

18

This probably changed with new versions of GnuPG as you can currently do this in one pipe:

$ gpg --with-colons --import-options show-only --import --fingerprint < secret.asc | awk -F: '$1 == "fpr" {print $10;}' 

Main game changer is option import-options which enables fake import. We simply work with file as it would be imported but it is not.

Option --with-colons guarantee stable and machine-parseable format which we use in last awk part.

awk simply prints 10th column from line with fingerprint (one starting with fpr).

2
  • 1
    Works for me, GPG 2.2.4 on Ubuntu 18.04, by far the simplest, nice one liner :) Commented May 28, 2020 at 9:41
  • Pls could you explain the --import-options show-only --import --fingerprint part? Thank You Commented Mar 11 at 14:51
8

Since gpg 2.2.8 (released mid-2018) there is an option --show-keys for showing keys without importing them, provided as a shortcut for --import --import-options show-only.

To show the key(s) in the file secret.asc:

$ gpg --show-keys secret.asc 

Different fingerprint format:

$ gpg --show-keys --with-fingerprint secret.asc 
7

As indicated in the comments, the simplest solution appears to be to first dearmor the key and then run --list-secret-keys on the new file:

$ gpg --dearmor secret.asc # Creates secret.asc.gpg $ gpg --with-fingerprint --no-default-keyring --secret-keyring ./secret.asc.gpg --list-secret-keys 

Annoyingly, although the dearmored key can be written to stdout with the -o - option, neither --secret-keyring - nor --secret-keyring /dev/stdin will allow the second command to read the key from stdin, so combining the two commands into one with a pipe isn't an option. Also, running the second command with gpg2 instead of gpg still fails to give the desired output.

A slightly more elaborate approach, but one that seems to work with both versions of gpg, is to import the secret key into a temporary GPG home directory and then list the temp home's private keys:

$ mkdir -m 0700 tmphome $ gpg --homedir tmphome --import secret.asc $ gpg --homedir tmphome --with-fingerprint --list-secret-keys 
1
  • 1
    Your second solution does work for me. The first does not. It will always fall back to the default key ring even when --no-default-keyring is specified. The man page of gpg states Note that GnuPG will not operate without any keyrings, so if you use this option and do not provide alternate keyrings via --keyring or --secret-keyring, then GnuPG will still use the default public or secret keyrings. Commented Jan 16, 2019 at 17:35

You must log in to answer this question.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.