It’s that time of the year again… Let’s renew our subkeys!
Checking for an expired subkey
GPGs messages are not that clear when a subkey expires. For example, Git may refuse to sign a commit with the cryptic message
gpg failed to sign the data. Or the journal logs a message
gpg-agent: command 'PKSIGN' failed: No secret key.
To check for an expired subkey use these commands:
# List all secret keys, there should be one line for your master key gpg -K # Edit the masterkey, this brings up the gpg console gpg --edit-key <MASTERKEYID> # List all subkeys > list # There should be one line that says `expired`
Renewing the expired subkey
Following good practice, I use a single offline master key without expiration date and multiple subkeys for signing and encryption. See here on how to set that up.
The subkeys are configured to expire annually. If everything was kept save, the expiration date can be changed without creating a new subkey. Use these commands on your (hopefully offline) master GPG home:
# Edit the masterkey, this brings up the gpg console gpg --home=path/to/offline/home --edit-key <MASTERKEYID> # List all subkeys >list # Select the subkey to renew, <n> is the number of the subkey in the list >key <n> # Now the subkey should be marked with an asterisk *. # Set a new expiration date >expire # Save the changes and close the console >save
Exporting/Importing the updated key
The subkey must now be transferred from the offline location to every computer that uses the subkey.
Run the following command to export the subkey into
subkey.key then copy that file to your computers.
# Export the secret subkey, note the ! after the id gpg --home=path/to/offline/home --armor --export-secret-subkeys <SUBKEYID>! > subkey.key
To import the key, run this command:
# Import the key gpg --import subkey.key # If you transfer keys between Windows and Unix you may get # gpg: [don't know]: partial length invalid for packet type 63 # This can be fixed by converting the line endings with dos2unix dos2unix subkey.key # Make sure the private key of your master key was NOT transferred by running gpg -K # and checking that the line for your master key says `sec#` and not `sec`.
Do not forget to update/republish your public key, for example on GitHub or GitLab. Since the same key is reused, you first have to delete the old version of the key and then re-upload the new version in the GitHub/GitLab settings.
# Export the public key with gpg --armor --export <MASTERKEYID>