2

I am a newcomer to GPG, and wanted to compare different ways of exporting keys, so I wrote the following shell script:

#!/bin/bash for key in "FE..." "17.." "BB.."; do # key_ids are trimmed here echo "processing keyid=${key}" echo "getting sha256sum for public key" gpg --export --armor "${key}" | sha256sum echo "getting sha256 sum for public key with !" gpg --export --armor "${key}!" | sha256sum echo "getting sha256 sum for private key" gpg --export-secret-key --armor "${key}" | sha256sum echo "getting sha256 sum for private key with !" gpg --export-secret-key --armor "${key}!" | sha256sum echo -e '\n\n' done 

I get the following output(note that I trimmed it as well):

processing keyid=FE... getting sha256sum for public key 2260... - getting sha256 sum for public key with ! 5499... - getting sha256 sum for private key 8d5c... - getting sha256 sum for private key with ! 407e... - processing keyid=17... getting sha256sum for public key 2260... - getting sha256 sum for public key with ! ce3d... - getting sha256 sum for private key 83ec... - getting sha256 sum for private key with ! 7da2... - processing keyid=BB.. getting sha256sum for public key 2260... - getting sha256 sum for public key with ! 2e36... - getting sha256 sum for private key 829d... - getting sha256 sum for private key with ! 111d... - 

So, it looks like if I run gpg --export key_id, I get the same public key if I print either the master(certify) key or any of the subkeys because I also export the whole key hierarchy. When I use gpg --export key_id!, only a specific(single) public key is being exported, which is useful to avoid exposing the master key.

I expected to see the same behaviour for gpg --export-secret-key key_id vs gpg --export-secret-key key_id!, where the former's output would be the same for every key_id because the whole private key hierarchy would be exported, while the latter's output would be unique. However, all of the private keys I get are unique. Why is that? Am I missing something?

1

1 Answer 1

3

The individual exported private keys are the same every time. What you're seeing as output is a collection of OpenPGP packets, including Secret Key Packtets and Secret Subkey Packets which contain the encrypted private keys. Encryption is randomized at multiple levels: When GPG derives the encryption key from your passphrase, it uses a random salt to make brute-force attacks more difficult. And when the private key is symmetrically encrypted with the derived key, then GPG uses a random initialization vector. So the output is supposed to be different. When you import the private key, you'll see it's always the same.

You can inspect the exact OpenPGP packets with

gpg --list-packets /path/to/exported/data 

In the secret key packet, you'll see a salt and a protect IV (the initialization vector) which change on each export.

The output of exporting a public key doesn't change, because there's no encryption and no other random parameters.

2
  • Thanks, this totally makes sense. To double-check one final thing, am I correct to assume that --export-secret-key key_id exports the whole secret key hierarchy while --export-secret-key key_id! exports a single secret key(the same way as --export key_id/key_id!)? Commented Dec 3, 2024 at 20:35
  • 1
    @Alex.Kh: Correct. Commented Dec 3, 2024 at 20:45

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.