0

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.

  • 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 Apr 24 '20 at 23:34
  • @Á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. – dave_thompson_085 Apr 25 '20 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 Apr 26 '20 at 0:34
2

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.

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"

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.