Skip to content

Digital Security

GPG (GnuPG)

Concepts

  1. fingerprint
  2. signature (make sure the source of the message is legit)
  3. certificate
  4. authentication

Encrypt, decrypt, sign & verify a file

gpg -r Tan -a -o data.doc.gpg -e data.doc  # encrypt data.doc for Tan
gpg -d data.doc.gpg  # decrypt the file
gpg --sign -r Tan -a -o data.doc.gpg -e data.doc  # encrypt along with signing
gpg --detach-sign --armor data.doc  # sign the data only
gpg --verify data.doc.sig data.doc  # verify the signature against the file

Export public & private keys

gpg --export -a "tan@tanli.dev" > public.key  # -a, --armor: content to ASCII
gpg --export-secret-key -a "tan@tanli.dev" > private.key

List private keys

gpg -K  # gpg --list-keys

Delete keys

gpg --delete-keys "tan@tanli.dev"
gpg --delete-secret-keys "tan@tanli.dev"

Load keys

gpg --import public.key
gpg --import private.key

Revoke keys

gpg -a --gen-revoke tan@tanli.dev > revocation_cert  # create a revocation certificate
gpg --delete-secret-keys tan@tanli.dev  # delete the secret keys
gpg -K  # list private keys
gpg --import revocation_cert  # reovke the key by importing the certificate
gpg -K  # list private keys
gpg --send-keys tan@tanli.dev --keyserver https://keyserver.ubuntu.com/  # publish to the keyserver

Receive public key from keyserver

gpg --keyserver pgp.mit.edu --recv-keys DAD95197

Restart GPG-Agent

gpgconf --kill gpg-agent

GPG: Setup Procedure

# create a tempory work directory
export GNUPGHOME=$(mktemp -d -t gnupg_$(date +%Y%m%d%H%M)_XXX)
# generate a harden configuration
wget -O $GNUPGHOME/gpg.conf https://raw.githubusercontent.com/drduh/config/master/gpg.conf
grep -ve "^#" $GNUPGHOME/gpg.conf

GPG Primary Key Generation

Generate a new primary key

gpg --full-generate-key

Create a new subkey

gpg --expert --edit-key "tan@tanli.dev"
gpg> addkey  # repeat this step each for sign, auth, encrypt
gpg> save  # save and exit GPG

GPG Subkey Renewal Procedure

Once the subkey expire, follow the following procedure:

  1. Re-generate the subkey based on its purpose
  2. Copy the new key to the 3 yubikeys

GPG Subkey Generation: Sign

gpg> addkey
Key is protected.

You need a passphrase to unlock the secret key for
user: "Tan Li <tan@tanli.dev>"
4096-bit RSA key, ID 0x233333333333, created 2016-10-28

Please select what kind of key you want:
   (3) DSA (sign only)
   (4) RSA (sign only)
   (5) Elgamal (encrypt only)
   (6) RSA (encrypt only)
   (7) DSA (set your own capabilities)
   (8) RSA (set your own capabilities)
Your selection? 4
RSA keys may be between 1024 and 4096 bits long.
What keysize do you want? (4096)
Requested keysize is 4096 bits
Please specify how long the key should be valid.
         0 = key does not expire
      <n>  = key expires in n days
      <n>w = key expires in n weeks
      <n>m = key expires in n months
      <n>y = key expires in n years
Key is valid for? (0) 1y
Key expires at Sat 28 Oct 2017 12:00:00 PM UTC
Is this correct? (y/N) y
Really create? (y/N) y
We need to generate a lot of random bytes. It is a good idea to perform
some other action (type on the keyboard, move the mouse, utilize the
disks) during the prime generation; this gives the random number
generator a better chance to gain enough entropy.

GPG Subkey Generation: Encrypt

gpg> addkey
Key is protected.

You need a passphrase to unlock the secret key for
user: "Tan Li <tan@tanli.dev>"
4096-bit RSA key, ID 0x233333333333, created 2016-10-28

Please select what kind of key you want:
   (3) DSA (sign only)
   (4) RSA (sign only)
   (5) Elgamal (encrypt only)
   (6) RSA (encrypt only)
   (7) DSA (set your own capabilities)
   (8) RSA (set your own capabilities)
Your selection? 6
RSA keys may be between 1024 and 4096 bits long.
What keysize do you want? (4096)
Requested keysize is 4096 bits
Please specify how long the key should be valid.
         0 = key does not expire
      <n>  = key expires in n days
      <n>w = key expires in n weeks
      <n>m = key expires in n months
      <n>y = key expires in n years
Key is valid for? (0) 1y
Key expires at Sat 28 Oct 2017 12:00:00 PM UTC
Is this correct? (y/N) y
Really create? (y/N) y
We need to generate a lot of random bytes. It is a good idea to perform
some other action (type on the keyboard, move the mouse, utilize the
disks) during the prime generation; this gives the random number
generator a better chance to gain enough entropy.

GPG Subkey Generation: Auth

gpg> addkey
Key is protected.

You need a passphrase to unlock the secret key for
user: "Tan Li <tan@tanli.dev>"
4096-bit RSA key, ID 0x233333333333, created 2016-10-28

Please select what kind of key you want:
   (3) DSA (sign only)
   (4) RSA (sign only)
   (5) Elgamal (encrypt only)
   (6) RSA (encrypt only)
   (7) DSA (set your own capabilities)
   (8) RSA (set your own capabilities)
Your selection? 8

Possible actions for a RSA key: Sign Encrypt Authenticate
Current allowed actions: Sign Encrypt

   (S) Toggle the sign capability
   (E) Toggle the encrypt capability
   (A) Toggle the authenticate capability
   (Q) Finished

Your selection? s

Possible actions for a RSA key: Sign Encrypt Authenticate
Current allowed actions: Encrypt

   (S) Toggle the sign capability
   (E) Toggle the encrypt capability
   (A) Toggle the authenticate capability
   (Q) Finished

Your selection? e

Possible actions for a RSA key: Sign Encrypt Authenticate
Current allowed actions:

   (S) Toggle the sign capability
   (E) Toggle the encrypt capability
   (A) Toggle the authenticate capability
   (Q) Finished

Your selection? a

Possible actions for a RSA key: Sign Encrypt Authenticate
Current allowed actions: Authenticate

   (S) Toggle the sign capability
   (E) Toggle the encrypt capability
   (A) Toggle the authenticate capability
   (Q) Finished

Your selection? q
RSA keys may be between 1024 and 4096 bits long.
What keysize do you want? (4096)
Requested keysize is 4096 bits
Please specify how long the key should be valid.
         0 = key does not expire
      <n>  = key expires in n days
      <n>w = key expires in n weeks
      <n>m = key expires in n months
      <n>y = key expires in n years
Key is valid for? (0) 1y
Key expires at Sat 28 Oct 2017 12:00:00 PM UTC
Is this correct? (y/N) y
Really create? (y/N) y
We need to generate a lot of random bytes. It is a good idea to perform
some other action (type on the keyboard, move the mouse, utilize the
disks) during the prime generation; this gives the random number
generator a better chance to gain enough entropy.

Yubikey + GPG/SSH

Yubikey initialization

gpg --card-status  # check the status of yubikey
gpg --card-edit  # configure the yubikey

Load private key to Yubikey

gpg --edit-key "tan@tanli.dev"
gpg> toggle
gpg> key 1  # locate key 1
gpg> keytocard  # move the key located to the card

Load Yubikey

gpg --card-edit
gpg/card> fetch  # config the public key address to github gist
gpg/card> quit
gpg --card-status

Yubikey with SSH Auth

# brew install openssh (OSX's default openssh is not enough)
ssh-keygen -t ed25519-sk

GPG Procedures

Reference

Setup on new computer with Yubikey

Step1: Insert the key to the computer
Step2: gpg --edit-card
card> fetch  # fetch public key
Step3: gpg --edit-key tan@tanli.dev
gpg> trust  # trust the key

Switch between Yubikeys

gpg-connect-agent "scd serialno" "learn --force" /bye

Config a new Yubikey

1. passwd & admin passwd
2. config public url

Renew Subkeys

Step1: Get access to the primary key
Step2: Extend the expire date via gpg --edit-key tan@tanli.dev
gpg> expire
Step3: Export the public key via gpg -a --export tan@tanli.dev > pub.sec
Step4: Publish the public key or import it on another machine via gpg --import pub.sec

SSH

Linode Security Guide

# login as root
apt update && apt upgrade
# set the timezone
timedatectl set-timezone 'America/Los_Angeles'
# set the hostname
hostnamectl set-hostname linode
# add a limited user account
adduser vm
adduser vm sudo
# logout and login as vm
exit
ssh vm@linode-ip
# harden ssh access
ssh-keygen -b 4096
sudo nano /etc/ssh/sshd_config
# restart the sshd
sudo systemctl restart sshd

Hardened /etc/ssh/sshd_config

X11Forward no
PermitEmptyPassword no