Skip to content
Vlad edited this page Nov 29, 2020 · 12 revisions

GPG

Encrypt files

# Encrypt sensitive file with passphrase
gpg --symmetric --passphrase "$ENCRYPT_KEY" --quiet --batch --yes --cipher-algo AES256 --s2k-digest-algo SHA512 --output .env.gpg .env

# Create BASE64 encoded string of the passphrase
echo "MyVeryStrongPassphrase" | base64

# Encrypt sensitive file with a BASE64 encoded passphrase
gpg --symmetric --passphrase "$(echo "$ENCRYPT_KEY64" | base64 --decode)" --batch --yes --cipher-algo AES256 --s2k-digest-algo SHA512 --output .env.gpg .env

# Encrypt multiple sensitive files
tar cz ansible_rsa ansible_vault_pwd | gpg --symmetric --passphrase "$(echo "$ENCRYPT_KEY64" | base64 --decode)" --batch --yes --cipher-algo AES256 --s2k-digest-algo SHA512 --output encrypted.tgz.gpg
# Decrypt file with passphrase
gpg --decrypt --passphrase "$ENCRYPT_KEY" --quiet --batch --yes --output .env .env.gpg

# Decrypt file with a BASE64 encoded passphrase (saving to disk)
gpg --decrypt --passphrase "$(echo "$ENCRYPT_KEY64" | base64 --decode)" --batch --yes --output .env .env.gpg

# Decrypt file with a BASE64 encoded passphrase (pipe to source directly)
. <( gpg --decrypt --passphrase "$(echo "$ENCRYPT_KEY64" | base64 --decode)" --batch --yes .env.gpg ) 2>/dev/null || true

New workflow

The general idea is to have a primary key, that has only one capability (Certify), with a very strong password, stored offline. This should be only used to generate subkeys, which will have (Sign, Authenticate and Encrypt capabilities), with their own passphrases and expiration dates.

Set-up working GPG home

export GNUPGHOME=$(mktemp -d)
export GPG_TTY=$(tty)
# Optionally copy the settings
cp ~/.gnupg/gpg.conf ~/.gnupg/gpg-agent.conf "$GNUPGHOME/"

Primary key

Import vgh primary key

pbpaste | gpg --import
# OR
gpg --import
# paste and type CTRL+D to exit
# Trust key (get fingerprint with `gpg --list-keys --fingerprint` and trim spaces)
echo '835A67B13547439017259E517A903650FCF51557:6:' | gpg --import-ownertrust

Change something in the primary key and export it (only passphrase)

gpg --expert --edit-key FCF51557
# Export primary key
gpg --armor --export-secret-key FCF51557 | pbcopy
# OR
gpg --armor --export-secret-key --output .vgh/.gnupg/FCF51557_master.pem FCF51557
shred -fu .vgh/.gnupg/FCF51557_master.pem

Subkeys

Add new subkey with a different passphrase, expiration, etc. Setting an expiry on a primary key is ineffective for protecting the key from loss - whoever has the primary key can simply extend its expiry period. Revocation certificates are better suited for this purpose. It may be appropriate for your use case to set expiry dates on subkeys.

gpg --expert --edit-key FCF51557
# passwd
# addkey; (8) RSA (set your own capabilities); (A) Toggle the authenticate capability (so that it reads: Current allowed actions: Sign Encrypt Authenticate); (Q) Finished; Key Size 4096; Valid for 1y;
# save

Export only the subkey

gpg --armor --export-secret-subkeys FCF51557 | pbcopy
# OR
gpg --armor --export-secret-subkeys --output .vgh/.gnupg/FCF51557.pem FCF51557

Clean up

rm -r "$GNUPGHOME" # Make sure it's the temporary one!!!
unset GNUPGHOME

Keyring

Delete the old key and import just the new one

gpg --delete-secret-and-public-keys FCF51557
gpg --import .vgh/.gnupg/FCF51557.pem FCF51557
echo '835A67B13547439017259E517A903650FCF51557:6:' | gpg --import-ownertrust

Old Workflow (updated September 4, 2017)

Backup ~/.gnupg

Set-up working GPG home

export GNUPGHOME=/tmp/.gnupg
export GPG_TTY=$(tty)

Make sure we start with a restrictive umask so that files and directories we write from this point forward are only accessible by the root user

```sh` umask 077


Import vgh primary key from Clipboard

```sh
pbpaste | gpg --import

Modify as needed (passphrase, subkeys, expiration, etc)

Export master key to Clipboard

gpg --armor --export-secret-key FCF51557 | pbcopy

Export keys to servers

gpg --send-keys FCF51557
keybase pgp update

Export sub keys to Clipboard (with a different password)

gpg --edit-key FCF51557 # -> passwd -> save
gpg --armor --export-secret-subkeys FCF51557 | pbcopy

Export pub keys

gpg --armor --export FCF51557 | pbcopy

Remove working GPG home

rm -r /tmp/.gnupg
unset GNUPGHOME GPG_TTY
export GNUPGHOME=~/.gnupg

Delete all keys

gpg --delete-secret-and-public-keys [email protected]

Import subkeys only

gpg --import vgh.sub.asc

Make sure master key is not present

gpg --list-secret-keys # should list 'sec#' for the private key

1.1. List keys

gpg --list-keys
gpg --list-keys --fingerprint # List with fingerprint
gpg --keyid-format SHORT -k FD1D730E # List short ID
gpg --keyid-format LONG -k FD1D730E # List long ID
gpg --list-secret-keys

1.2. Export GPG keys

Note: --armor makes a readable output not binary

gpg --output vgh.pub.asc --armor --export [email protected]
gpg --output vgh.asc --armor --export-secret-key [email protected]
gpg --output vgh.subkeys.asc --armor --export-secret-subkeys [email protected]
gpg --output vgh.subkey1.asc --armor --export-secret-subkeys 474DECCA! # Export single subkey (Note the exclamation mark)

1.3. Trust level

gpg --edit-key [email protected] -> trust -> 5 -> quit
# OR
echo$(gpg --fingerprint [email protected] | grep Key|cut -d= -f2 | sed 's/ //g' | head -n 1)${TRUSTLEVEL}> ownertrustlevel
gpg --import-ownertrust ownertrustlevel
gpg --update-trustdb && gpg --refresh-keys

1.4. Change password

gpg --edit-key [email protected] -> passwd -> quit

1.5. Change expiration

gpg --edit-key FD1D730E
> key 0 # deselects all subkeys and selects the primary
> key 1 # selects the first subkey
> expire # changes the expiration date
> save # save changes

gpg --send-keys FD1D730E
keybase pgp update

1.6. Subkeys

gpg --edit-key [email protected] > addkey

1.7. Keybase

  • Import public
curl -sSL https://keybase.io/vgh/key.asc | gpg --import -
  • Update servers
keybase pgp update

1.8. Key servers

gpg --send-key FCF51557
gpg --keyserver pgp.mit.edu --send-key FCF51557
gpg --keyserver keys.gnupg.net --send-key FCF51557

1.9. MISC

  • Use a separate, temporary home (same as --homedir /tmp/.gnupg appended to each command)
export GNUPGHOME=/tmp/.gnupg
unset GNUPGHOME # when finished
  • Remove master key from keychain
gpg --delete-secret-key FCF51557
  • Find the keygrip for the master key and remove it
gpg2 --list-secret-keys --with-keygrip
gpg-connect-agent 'DELETE_KEY 35F797A0FD9320373F7672FF9A3043936F44F14F' /bye
gpg --list-secret-keys # should list 'sec#' if the private key is missing
  • Print private key
gpg --export-secret-key FCF51557 | paperkey --output FCF51557.txt
shred FCF51557.txt

1.10. Resources