I use a GPG key to sign my git commits.
An error like this one might be a sign of an expired GPG key.
error: gpg failed to sign the data fatal: failed to write commit object
- On your machine, open up the shell (git bash on Windows) and type
gpg --list-secret-keys --keyid-format LONG
- This will list out all your secret keys in the following fomat:
/home/TheSherlockHomie/.gnupg/pubring.kbx
---------------------------------
sec rsa4096/HJ6582DC8B78GTU 2020-12-09 [SC] [expires: 2025-05-01]
15JHUG1D325F458624HF7521B3F5D82DC458H
uid [ultimate] TheSherlockHomie (Key to sign git commits) <[email protected]>
ssb rsa4096/11HGTH5483DD0A 2020-12-09 [E] [expires: 2025-05-01]
- If your keys are expired, you'll se
expired
instead of the expiration date.
- Now that you know for sure that your commit signing key has expired, let's renew the expiration date:
gpg --edit-key KEYID
// where KEYID is of the key you want to renew. Here, it is HJ6582DC8B78GTU
- Now in the intearctive gpg shell,
gpg> expire
- When prompted type
1y
or however long you want the key to last for. - Now to renew all our subkeys too.
key 1
key 2 //and so on, depending on the subkeys you have
- A star will sppear before all selected keys.
gpg> expire
- Again, set the expiration time for your subkeys.
- Since the key has changed, we now need to trust it. We might get a warning
There is no assurance this key belongs to the named user
otherwise.
gpg> trust
- Set the trust level
5
(for ultimate) or whatever is the trust level of the key.
gpg> save
- For the gpg key you updated, export its public key:
$ gpg --armor --export KEYID
# Prints the GPG key ID, in ASCII armor format
- Copy your GPG key, beginning with
-----BEGIN PGP PUBLIC KEY BLOCK-----
and ending with-----END PGP PUBLIC KEY BLOCK-----
- Navigate to
Github>Settings>SSH and GPG keys
- Delete the expired key.
- Add the new key that you copied.
- "Your previous commits and tags will show as verified, as long as the key meets all other verification requirements." - Github
- There is more than one way to accomplish this.
- The method I prefer is:
gpg --output backupkeys.pgp --armor --export-secret-keys --export-options export-backup [email protected]
- This will create a file
backupkeys.pgp
on your present working directory. Make sure to store it safely. - If this key is important to you, you may want to print out the key on paper using paperkey, and store it in a fireproof/waterproof safe.
- Now export the trust database
gpg --export-ownertrust > ownertrust-gpg.txt
- This will create a file
ownertrust-gpg.txt
on your present working directory. Keep it along with your backup keys.
- You might have multiple machines where you need the key, or you might have a setup like me, where I use Ubuntu on WSL and Windows both for development.
- Transfer the keys to your machine, open a shell (or Git Bash), and type:
gpg --import backupkeys.pgp
gpg --import-ownertrust ownertrust-gpg.txt
- Now verify that you have the keys
gpg --list-secret-keys --keyid-format LONG
gpg --list-keys --keyid-format LONG
- Which should show your secret and public keys respectively.
- If you do not have the owner trust backup file, you'll need to manually set the trust level:
gpg --edit-key KEYID
gpg> trust
- And set the trust level accordingly.
-
krisleech - Renew Expired GPG key (Github Gists)(And shirohana, with the comment reminding to save your work)
-
Thomas Eisenbarth - GPG: Extract private key and import on different machine (on makandracards.com)
-
chrisroos - Instructions for exporting/importing (backup/restore) GPG keys (on Github Gists)
You can safely delete and re-add the renewed public key β it won't cause any issues.
Some people say there's no need to delete the existing public key before adding the new one. However, if you don't update the public key, clicking the Verified button may show that the key is verified but expired.
By deleting the old public key and adding the renewed one, you remove the expired status and ensure the key is up to date.