Digital Security¶
GPG (GnuPG)¶
Concepts
- fingerprint
- signature (make sure the source of the message is legit)
- certificate
- 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:
- Re-generate the subkey based on its purpose
- 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¶
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¶
# 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