I've got the following set of 6 subkeys

$ gpg -K
ssb>  rsa2048 2017-10-04 [E] [expires: 2027-10-02]
ssb>  rsa2048 2017-10-04 [S] [expires: 2027-10-02]
ssb>  rsa2048 2017-10-04 [A] [expires: 2027-10-02]
ssb>  rsa2048 2015-02-12 [E] [expires: 2025-01-05]
ssb>  rsa2048 2016-01-05 [A] [expires: 2026-01-02]
ssb>  rsa2048 2016-08-20 [S] [expires: 2026-08-18]

The context is that I bought a new smart card (Yubikey) and generated new subkeys for it. I wanted to keep record of old subkeys in my pubkey so that e.g. Github keeps displaying my old commits signed with old subkeys as "verified".

However I'd like to make sure that from now on only new subkeys are primarly used. e.g. If someone sends me an encrypted message I want them to use the new subkey.

I noticed gpg -e uses my new encryption subkey by default, so this works as intended, but my question is why?

In other words how does gpg determine which key to use during encryption? Is it based on order in which subkeys are saved in the file (as above) or creation/expiration date (newer has priority)?

1 Answer 1


GnuPG always selects the newest valid (sub)key for the respective operation (usually, the newest non-revoked key with a supported algorithm). Even if you select a specific subkey, GnuPG first resolves the associated primary key and then starts this selection process. To override this, postfix ! to a given key. This is something you might for example do in your git configuration if required.

I am not aware of any normative reference though (apart from the GnuPG code): neither RFC 4880 (OpenPGP) nor the GnuPG man page or manual seem to define the behavior. The relevant lines of code from the key comparison function:

if (old->validity == new->validity && uid_is_ok (&new->key, uid)
    && old->creation_time < new->creation_time)
  return -1;      /* Both keys are of the same validity, but the
                     NEW key is newer.  */

You must log in to answer this question.

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