gnugp is very useful to encrypt files using a public key – this allows you to create backups without sharing a keyfile. But it’s a bit tricky to explicitly use a public-keyfile instead of the global keyring via fingerprint.

Directory Structure#

This script creates a custom .gnupg directory (gpg home) in the current working directory to store the private keys + keyrings.

├── decrypt.sh
├── encrypt.sh
├── genkey.sh
├── .gnupg
│   ├── openpgp-revocs.d
│   ├── private-keys-v1.d
│   │   ├── 9FF82585023FB486AE07891AC94159A68B59D68C.key
│   │   └── E04C0621BA0FF3D28BA9BEEE91274000DD3E19D5.key
│   ├── pubring.kbx
│   ├── pubring.kbx~
│   └── trustdb.gpg
├── publickey.gpg
└── test
    ├── data.txt
    └── data.txt.gpg

Create a private key programmatically#

File: genkey.sh

#!/usr/bin/env bash

# create storage dir
echo "creating storage directory.."
mkdir -p .gnupg/private-keys-v1.d
chmod 0700 .gnupg

# generate private key
echo "generating private key.."
gpg \
    --no-options \
    --no-default-keyring \
    --homedir .gnupg \
    --gen-key \
    --batch - <<EOM
Key-Type: 1
Key-Usage: cert
Key-Length: 4096
Subkey-Type: 1
Subkey-Usage: encrypt
Subkey-Length: 4096
Name-Real: backup_service
Name-Email: backup@aenon.rocks
Expire-Date: 0
Passphrase: test

%commit
%echo gpg key created
EOM

# extract publickey
echo "extracting public key.."
gpg \
    --no-options \
    --homedir .gnupg \
    --export \
    "backup_service" > publickey.gpg

# show key
echo "info:"
gpg --import-options show-only --import --fingerprint --with-subkey-fingerprints publickey.gpg

Encrypt a file using the public-key file#

File encrypt.sh

#!/usr/bin/env bash

set -e

echo "encrypting file.."

gpg \
    --no-options \
    --no-default-keyring \
    --primary-keyring ./publickey.gpg \
    --encrypt \
    --cipher-algo AES256 \
    --always-trust \
    --no-random-seed-file \
    -r "backup_service" \
    test/data.txt

Decrypt a file using private-key#

File decrypt.sh

#!/usr/bin/env bash

set -e

echo "decrypting file.."

gpg \
    --no-options \
    --no-default-keyring \
    --homedir .gnupg \
    --decrypt \
    --default-recipient-self \
    --output data2.txt \
    test/data.txt.gpg