GPG Encryption

Key Management

Basic Commands

# list public keys
$ gpg --list-keys

# list private keys
$ gpg --list-secret-keys

# import private/public key
$ gpg --import /path/to/key.asc

Create New Key

  1. Run gpg --full-generate-key
  2. Answer 1, 3072, 0, y
  3. Enter your real name, email, no comment, and O
  4. Enter a password twice to finish

Export A Key

  1. Run gpg --list-secret-keys
    • Run gpg --list-keys for public key
  2. Copy the 40 chars KEY_ID
  3. Run gpg --export-secret-keys --armor KEY_ID > my-private-key.asc
    • For public key, run gpg --export --armor KEY_ID > my-public-key.asc
  4. Enter password when prompted

Delete A Key

  1. Run gpg --list-secret-keys
    • For public key, run gpg --list-keys
  2. Copy the 40 chars KEY_ID
  3. Run gpg --delete-secret-keys KEY_ID
    • For public key, run gpg --delete-keys KEY_ID
  4. Confirm and enter password to delete

Delete A Subkey

  1. Run gpg --list-secret-keys
  2. Run gpg --expert --edit-key KEY_ID
  3. Look at all the ssb keys, indexed from 1 ignoring the first sec key
  4. Type key 2 to choose second ssb key
  5. Type delkey and y to confirm then quit and y to save changes

Encryption

Encrypting Messages

# Encrypt message by prompting for recipient's email
$ gpg --encrypt message.txt

# Encrypt for specific recipient
$ gpg  --recipient user@domain.com --encrypt message.txt

# Encrypt in ASCII format
$ gpg  --armor --recipient user@domain.com --encrypt message.txt

# Encrypt and sign at the same time
$ gpg --encrypt --sign --recipient user@domain.com message.txt

# Specify output file
$ gpg --output message.txt.gpg

Decrypting Messages

# Will automatically prompt for passphrase if symmetric
$ gpg -d message.txt.gpg

# Decrypt and put output in decrypted.txt
$ gpg --decrypt message.txt.gpg > decrypted.txt

Importing Existing SSH Key

  1. Convert your private key to PEM format (if your key starts with -----BEGIN OPENSSH PRIVATE KEY-----)
    • Skip if your private key starts with -----BEGIN RSA PRIVATE KEY-----
    $ ssh-keygen -p -m PEM -f /path/to/ssh/key
    
  2. Create a temporary keystore from your current GPG keystore
    $ gpg --list-secret-keys  # copy KEY_ID
    $ gpg -a --export-secret-keys KEY_ID > exported_gpg_key.asc
    $ mkdir temp_gpg
    $ chmod go-rwx temp_gpg/
    $ gpg --homedir temp_gpg/ --import exported_gpg_key.asc
    $ gpg --homedir temp_gpg/ --list-secret-keys  # verify key imported correctly
    
  3. Convert and import existing SSH key as standalone GPG key
    $ brew install monkeysphere  # yum or apt for Linux
    $ pem2openpgp temporary_id < /path/to/ssh/key  | gpg --import --homedir temp_gpg/
    
  4. Add existing SSH key as subkey into GPG key
    $ gpg --homedir temp_gpg/ --list-secret-keys --with-keygrip  # copy keygrip for temporary_id
    $ gpg --homedir temp_gpg/ --expert --edit-key KEY_ID
    $ addkey
    $ Your selection? 13
    $ <Paste the temporary_id keygrip>
    $ Your selection? s
    $ Your selection? e
    $ Your selection? a
    $ Your selection? q
    $ Key is valid for? (0) 0
    $ Is this correct? (y/N) y
    $ Really create? (y/N) y
    $ quit
    $ Save changes (y/N) y
    
  5. Export GPG key with new SSH subkey
    $ gpg --homedir temp_gpg/ -a --export-secret-keys KEY_ID > gpg_key_with_ssh_subkey.asc
    
  6. Import new GPG key with SSH subkey into primary GPG keystore
    $ gpg --import gpg_key_with_ssh_subkey.asc
    

SSH with GPG Subkey

  1. Add an authentication subkey
    $ gpg --list-secret-keys  # get KEY_ID
    $ gpg --expert --edit-key KEY_ID
    $ addkey <enter>
    $ Your selection? 8
    $ Your selection? s
    $ Your selection? e
    $ Your selection? a
    $ Your selection? q
    $ What keysize do you want? (3072) 3072
    $ Key is valid for? (0) 0
    $ Is this correct? (y/N) y
    $ Really create? (y/N) y
    $ quit
    $ Save changes? (y/N) y
    
  2. Enable SSH support
    $ echo 'enable-ssh-support' >> ~/.gnupg/gpg-agent.conf
    
  3. Specify SSH authentication key to use
    $ gpg --list-keys --with-keygrip  # copy Keygrip with [A] or [AR]
    $ echo KEYGRIP_ID >> ~/.gnupg/sshcontrol
    
  4. Start gpg-agent and connect with SSH, add to ~/.zshrc or ~/.bashrc
    export SSH_AUTH_SOCK="$(gpgconf --list-dirs agent-ssh-socket)"
    gpgconf --launch gpg-agent
    gpg-connect-agent updatestartuptty /bye >/dev/null
    
  5. Export and copy SSH public key to remote hosts
    $ gpg --list-keys              # copy KEY_ID
    $ gpg --export-ssh-key KEY_ID  # copy and add to ~/.ssh/authorized_keys on remote host