(setq plaintext 'everywhere)



Gnupg Backup
Backup Your GPG Private Keys And Settings

Table of Contents

1 Backup

[2023-08-28 Mon]

Get a list of all uid's with keys on you system:

gpg --list-secret-keys
/home/br/.local/share/gnupg/pubring.gpg
---------------------------------------
sec   rsa4096 2022-09-19 [SC]
      018875D477884685DD4737A32E650629543EECA3
uid           [ultimate] Pacman Keyring Master Key <pacman@localhost>

sec   rsa4096 2023-08-22 [SC]
      EF492D56F73B9C3D547780A5C58F5BDFB7D2DCA3
uid           [ultimate] <YOUR_ID>
ssb   rsa4096 2023-08-22 [E]

Export your private key using YOUR_ID as found in the previous command:

gpg --output private-key.asc --export-options backup --export-secret-keys --armor <YOUR_ID>

Export the trust database:

gpg --export-ownertrust > otrust.txt

Backup gpg.conf, just copy it, and backup pubring.kbx or pubring.gpg, pubring.gpg could be named pubring.kbx. Only do this if you have public keys in your key ring that need to be saved. You do not need to backup your own public key because it is part of your private key.

gpg --output public-keys.asc --export --armor --keyring <path/to/pubring.gpg>

Back up the revocation certificate, these are stored in gnupg/openpgp-revocs.d, note this backup should be stored somewhere else than the place you backup your private keys since part of its utiliy comes from having no longer access to your private key. Alternatively you can store the certificate, private keys and everything else in multiple places. The certificates can also be generated with:

gpg --gen-revoke --armor --output revcert.asc <YOUR_ID>

Place all these files in a directory and encrypt it with a strong password, note in the command below gpg-backup is the directory with your private key, etc:

gpgtar --output gpg-backup.gpg \
       --symmetric \
       gpg-backup

2 Restore

Decrypt the tarbal:

gpgtar --decrypt gpg-backup.tar

Restore the public keys:

gpg --import public-key.asc

Restore the private key:

gpg --import-options restore --import private.asc

Restore the trust database:

gpg --import-ownertrust < otrust.txt

and also copy gnupg.conf into your gnupg directory.

2.1 Manually Setting The Trust Of Your Key

gpg --edit-key your@id.here
gpg> trust
Your decision? 5

3 Script

Simple script to automate the backing up and restoring process.

#!/usr/bin/env sh

# Description:
# Backup your gpg keys and settings or import them.
#
# Dependencies:
# - gnupg

set -ex

usage() {
    cat << EOF
Usage: $0 import | export
    import _directory_,
           import a gpg encrypted tar archive created with the
           export option.
    export, export a chosen gpg private key, owner trust, public
            keys, gpg.conf, revocation of the private key
EOF
}


: "${GNUPGHOME:=$HOME/.gnupg}"

case "$1" in
    e|export)
        backup_dir=gnupg-backup-"$(date '+%Y%m%d')"
        mkdir "${backup_dir}" || exit 1
        gpg --list-secret-keys
        echo 'Which uid to backup: '
        read -r uid
        # echo 'Do you want to backup the public key ring [y/n]: '
        # read -r backup_pubring
        cd "${backup_dir}" || exit 3
        gpg --output private-key.asc \
            --export-options backup \
            --export-secret-keys \
            --armor \
            "${uid}"
        gpg --export-ownertrust > otrust.txt
        gpg --output public-keys.asc \
            --export \
            --armor #\
            # --keyring "$(find "${GNUPGHOME}" -type f -name 'pubring.*[^~]')"
        [ -f cp "${GNUPGHOME}"/gpg.conf ]       && cp "${GNUPGHOME}"/gpg.conf .
        [ -f cp "${GNUPGHOME}"/gpg-agent.conf ] && cp "${GNUPGHOME}"/gpg-agent.conf .
        fingerprint="$(gpg  --fingerprint --keyid-format long "${uid}" \
                            | awk -F= '/Key/ { gsub(/[[:blank:]]/, "", $2); print $2 }')"
        # consider backing up entire openpgp-revocs.d directory
        gpg --gen-revoke --armor --output "${fingerprint}.rev" "${uid}"
        cd .. || exit 3
        gpgtar --output "${backup_dir}".gpg \
               --symmetric \
               --gpg-args '--cipher-algo AES256 --s2k-digest-algo SHA512 --s2k-count 65536 --armor' \
               "${backup_dir}"
        ;;
    i|import)
        [ -f "${2}" ] || { usage; exit 2; }
        # num="$(find . -maxdepth 1 -type d -name '*_.+_')"
        output_dir="${2%.gpg}"
        mkdir -pv "${output_dir}" || exit 1
        gpgtar --directory "${output_dir}" --decrypt "${2}"
        backup_dir="$(find "${output_dir}" -mindepth 1 -maxdepth 1 -type d)"
        cd "${backup_dir}" || exit 3
        gpg --import public-keys.asc
        gpg --import-options restore --import private-key.asc
        gpg --import-ownertrust < otrust.txt
        mkdir -pv  "${GNUPGHOME}"/openpgp-revocs.d \
              && cp *.rev "${GNUPGHOME}"/openpgp-revocs.d
        [ -f gpg.conf ]       && cp gpg.conf "${GNUPGHOME}"
        [ -f gpg-agent.conf ] && cp gpg-agent.conf "${GNUPGHOME}"
        ;;
    *) usage; exit 4; ;;
esac

exit

4 Just Backing Up Your Private Keys

Encrypting1

gpg --output pubkey.gpg --export SOMEKEYID \
    && gpg --output - --export-secret-key SOMEKEYID \
        | cat pubkey.gpg - \
        | gpg --armor --output keys.asc --symmetric --cipher-algo AES256

Decrypting1

gpg --output - keys.asc | gpg --import

5 Moving GPG keys privately

This method1 allows you to very easily move you key from one computer to another. It does require you to have ssh access to that computer.

If you’re on the machine that already has the key:

gpg --export-secret-key SOMEKEYID | ssh othermachine gpg --import

If you’re on the machine that needs the key:

ssh othermachine gpg --export-secret-key SOMEKEYID | gpg --import

6 Sources

Footnotes:



If something is not working, please create an issue here.