1

I’m learning about key management, encryption and GPG for provenance (verifying authorship). Using DevDungeon’s GPG Tutorial I learned that to export your GnuPG private key to your local computer, you use this command: $ gpg --export-secret-keys --armor XXX > ./my-priv-gpg-key.asc (where XXX is your unique hexadecimal identifier). Yesterday I used this command to generate the secret plain text secret key which I moved to cold storage. But today I invoked the same gpg command and entered the same passphrase which generated a new plain text secret key. I compared the two (yesterday’s key and today’s key) using the same utility I use to view changes made to source code in git (p4merge). I noticed that the two gpg keys are slightly different. Roughly half is the same and the other half is brand new.

Now for my uber naive questions:

  1. Is this a bad idea? If so, could someone clarify why this is a bad idea?
  2. Should I only use the first one and delete the second one? Or is it perfectly alright for me to use either one going forward? Which one should I use?

I Googled 'generating duplicate gpg private keys' and similar search terms but I had a hard time finding a discussion regarding my questions above. I also Googled ‘managing multiple private keys gnupg’ which turned up links to the official GnuPG manual on the topic of Key Management which was interesting but doesn’t answer my questions specifically.

3
  • Most probably, they are equivalent. However, it's worth noting that testing that, the command above produces the same input. Did you change anything in the key in the meantime? Compare the output of running gpg --list-packets on both files.
    – Ángel
    Commented Apr 24, 2020 at 23:34
  • 1
    @Ángel: it's the same through 2.0, but different for 2.2; see my answer. --list-packets shows the decrypted values (assuming you give it the password), and thus doesn't show the difference. Commented Apr 25, 2020 at 2:30
  • Of course! Indeed, I was testing with a pre-2.2 version. The salt difference made sense, and it was a bit puzzling that I did not get that. It's true that later versions need to re-encrypt the private key.
    – Ángel
    Commented Apr 26, 2020 at 0:34

2 Answers 2

4

It's version dependent.

First, a clarification. The output of almost any GPG command using --armor/-a is text form, that is the data is base64-encoded with header/trailer lines and a checksum added. In the past this was done to allow transmission over email which last century couldn't handle binary data; today it is rarely if ever needed for that purpose, but is still convenient for other things that can't handle binary, like cut&paste -- and HTML. (People sometimes try to post binary data on Stack and it never comes out usable, but posting 'armored' data, or similarly 'PEM' data used by OpenSSL and some other things, works right.)

It is not however plaintext, or not all. In cryptography, plaintext or cleartext specifically means not encrypted, and part of a PGP 'secret' key or subkey block is encrypted. The rest of it, containing the publickey value, userid, and affirming (aka 'certifying') signatures, is not encrypted, and is plaintext -- whether in binary or armored/text form.

In particular, the privatekey part of the OpenPGP (RFC4880) form of 'secret' key is encrypted using password-based encryption which, for reasons discussed in many other Qs you can search for, uses iterated hashing with random 'salt' which means if the same data is encrypted multiple times it produces different ciphertexts (with overwhelming probability).

Versions of GPG up to 2.0 use the OpenPGP form internally, in .gnupg/secring.gpg, so each time you export the same key it produces the same external form. GPG 2.2 changed to a new (gcrypt-based) file format in .gnupg/private-keys-v1.d/* so now when you export it must re-encrypt the data into the OpenPGP format, and because of salt as above the encrypted portion (ciphertext) is different each time. However the (plaintext) data it is encrypted from, and when used decrypts to, is the same.

Added: while checking something else, I discovered this is (now) in the manual:

--export-secret-keys ... GnuPG may ask you to enter the passphrase for the key. This is required, because the internal protection method of the secret key is different from the one specified by the OpenPGP protocol.

Also found a neardupe gpg: Every private key export (of the same key-pair) is different

1
  • The only issue is how to I pass the passphrase via command line in automations for pipelines ? I can't find a good guide on that anywhere
    – unbox-us
    Commented Jan 20, 2023 at 6:27
1

When you run the command gpg --export-secret-keys ... the exported secret keys are encrypted. So comparing the two files should yield the result you have noticed. If you exported the same key the same way each time, then regardless of the contents of the files, they should be the same key.

You could test this by importing both of the files, using

gpg --import --verbose my-private-gpg-key1.asc
gpg --import --verbose my-private-gpg-key2.asc

Each time it should say something like "secret key already exists"

You must log in to answer this question.

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