Yubikey tutorial for cyber security and privacy

What is GPG and PGP?

PGP stands for Pretty Good Privacy and is the encryption software developed by Philip R. Zimmermann then commercialized by a security software company. Ironically, he was accuesed for allegedly violating the Arms Export Control Act because CIA cannot read your emails anymore. CIA is an organization full of people with good intentions and they just want to read emails from some terrorists in order to protect citizens. Since no one can trust the encryption software owned by a company, people came up with OpenPGP, which is an open source standard for encryption technologies.

GPG stands for GNU Privacy Guard. GPG is a different implementation of the Open PGP standard and a strong alternative to Symantec’s official PGP software. Critical softwares such as GPG and PGP won’t be trusted by people if they are not scrutinized under the public eyes.

Build a Web of Trust

https://xkcd.com/

Why spend $100 on two Yubikeys not Wagyu steak?

Because passwords are obviously not able to protect you from cyber attacks to take over your accounts on the internet at all as they claim to but mathematics can save you from being hacked even though in reality you are still not 100% safe. If you hold one billion bitcoins and pass the private key on an encrypted channel, those malicious attackers won’t mind spending 10 million dollars to rent super computers and wait 10 years to crack you open or the State can do it for free. However, encryption with physical security key significantly increases the difficulty and time to compromise your password or private key.

Yubikey has secrets written in its two internal slots that cannot be extracted or cloned and three wrong attempts to enter the PIN will detonate an atomic bomb inside to destroy the secrets forever unless the Yubico company was asked by NSA to maintain a secret copy of the serial number of your key and its secrets or you are tortured in a black jail to give away the PIN before you are cut into pieces. Actually after 3 wrong attempts you have to enter the Admin PIN to unlock it so in total you are given 9 attempts before the key becomes irrecoverable. You probably can’t fool the interrogators 9 times in a black jail. I believe Yubikey let you change the maximum number of wrong attempts somewhere in the setting.

Two-step authentication with FIDO2

Literally the best way to protect you from unauthorized login and passwords should be abandoned in the future. I used to think two factor authentication from text messages is enough to provide security until I learned someone can even build a fake celluar signal tower to hack you when you are the CEO of a crypto exchange company.

The setup is too simple to even mention: 1. Plug in the yubikey to register the key on the websites that support FIDO2 two-factor authentication. 2. Next time you log in, the website asks you to insert your key and touch it to authenticate.

Set up GPG with Yubikey

If you are paranoid enough to believe that the Big Brother colluded with Bill Gates and installed a hidden TeamViewer on your Windows machine to monitor every single one of your moves, I highly recommend using Tails: A portable Operating System that protect against surveillance and censorship from an USB stick in a clean offline environment to generate the key and import it into Yubikey. Use on-screen keyboard if you are even more paranoid to believe your keyboard is wiretapped. For what? The nano robots injected into your body from the Covid vaccine can still read your mind! Just kidding. Come on you are not that rich and important. Hackers and Big Brothers won’t give a shit about you and this post is only for powerful people like Angela Merkel so don’t waste $100 on two Yubikeys while you can eat some good Wagyu steak instead. Or maybe you want to claim superiority over less tech-savvy people who lowkey judge you for not using an iPhone and think iPhone provides the best security:)

For creating a bootable media, Ventoy is so far the best tool to create multiple bootable USB installation drives without even burning a new OS into the USB stick every time like in old days but just copy multiple ISO images to your USB stick and Ventoy will magically let you choose which OS to boot from at startup.

Generate GPG keys

Master secret key is the ultimate source of reputation while subkeys (signing keys, encryption keys and authentication keys) are associated with and derived from the master key. Master key can revoke them if subkeys are compromised. * Generate master secret key and list keys in editing mode. <KEYID> could be your name, email you used in master key genertion (easy to remember and type) or the long unique ID of your key. By default, an encryption subkey is generated together with master key but we can generate it again.

1
2
3
# Enter name, email, passphrase and choose RSA4096
gpg --expert --full-generate-key
gpg --edit-key <KEYID>

  • Add subkey for signing and save the key otherwise the key will disappear when you exit the editing mode

    1
    2
    3
    4
    gpg> addkey
    # RSA (sign only)
    gpg> 4
    gpg> save

  • Add subkey for encryption

    1
    2
    3
    4
    gpg> addkey
    # RSA (encrypt only)
    gpg> 6
    gpg> save

  • Add subkey for authentication

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    gpg> addkey
    # RSA (set your own capabilities)
    gpg> 8
    # Possible actions for a RSA key: Sign Encrypt Authenticate
    # Current allowed actions: Sign Encrypt
    # Disable Sign
    gpg> S
    # Disable Encrypt
    gpg> E
    # Turn on Authenticate
    gpg> A
    # Finished
    gpg> Q
    gpg> save

  • Delete one of the keys for encryption (Optional)

    1
    2
    3
    4
    # Select the key
    gpg> key 1
    gpg> delkey
    gpg> save

  • Back up keys. Note that master secret keys cannot be exported to yubikeys and you should make a backup. Only subkeys, signing keys and encryption keys can be exported and you may want to make a backup for subkeys too

    1
    2
    3
    gpg --armor --export-secret-key <KEYID> >> /some/secure/location/<KEYID>-master.key
    gpg --armor --export-secret-subkeys <KEYID> >> /some/secure/location/<KEYID-sub>.key
    gpg —-import /path/to/secret-key-backup.asc

  • Upload to the key server so everyone knows your public key gpg --keyserver hkp://keys.gnupg.net --send-key 48CCEEDF

  • Follow this link How to revoke keys if you want to revoke a key. The revoke certificate is like an encrypted message with the word “REVOKED” in it and when you upload that encypted message to the keyserver, the keyserver will notify anyone who downloads your public key that your key is compromised but if someone only gives you this public key in private you won’t know if that key is revoked or not.

Move keys to store on Yubikeys

Plug in your yubikey and may need to enter your Admin PIN. The keytocard operation is destructive that it will remove the local copy once the keys are moved into the Yubikeys so it’s your responsibility to make a backup for subkeys if you want to recover the subkeys or copy the subkeys to another backup Yubikey. Using only one key for all signing, encryption and authentication may have security vulnerbilities that could be exploited to compromise your keys and that’s why we have 3 separate subkeys for each purpose.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
# Select the signing key
gpg> key 1
gpg> keytocard
# Please select where to store the key: (1) Signature key (3) Authentication key
# Unselect the signing key
gpg> key 1
# Select the encryption key
gpg> key 2
gpg> keytocard
# Unselect the encryption key
gpg> key 2
# Select the authentication key
gpg> key 3
gpg> keytocard
gpg> save
Use gpg --edit-card to check if the subkeys are imported correctly into the yubikey.

Export public key for SSH authentication

Storing the private keys on your machine for SSH is never a good idea because the keys could be easily accessed from memory or disk when you machine is hacked. Even though your private key is protected by a passprase, it takes only seconds to break it if your passphrase is “helloworld” or maybe weeks for a little longer passphrase.

  • Export the public key for SSH authentication, it’s the public key that associated with the subkey for authentication not for signing and encryption purposes.
    1
    gpg --export-ssh-key <KEYID> > XXX.pub
    The signing subkey is used for signing git commits and we don’t need to export the siging subkey. If we jump to a new machine and our keys are not in the keyrings, we need to export masterkey and subkeys or download them from a key server, then import them into gpg keyring with gpg --import XXX.pub and check if our keys are imported with gpg --list-keys.
  • Enable SSH and Putty support on gpg-agent by changing it in GUI or this can be done by adding the line enable-putty-support to gpg-agent.conf in C:\Users\%USER%\AppData\Roaming\gnupg on Windows. For linux environment, create a file ~/.gnupg/gpg-agent.conf and add enable-ssh-support to it. Next time you connect to a server with SSH, it uses the private key on your smart card first and then fall back to traditional SSH authentication when the smart card is not available. In this way, Github knows it’s really you (the yubikey owner) who pushed the commit not someone who stole your private key and passprase.
  • Publish your public key XXX.pub to a key server so other people can download your key and sign your key to build a network of trust. The key server where I upload all my public keys is https://keys.openpgp.org/ and your email address needs to be verified.

Sign your git commits with GPG

  • Export public key gpg --armor --export KEYID > KEYID.asc and upload the public key to Github.
  • Install GPG4Win and run Kleopatra to enable gpg-agent that can detect keys and pop up prompts for you to enter PIN or password. If gpg --edit-card does not show card info, go to settings in Settings/Configure Kleopatra/GnuPG System/smartcards and add Yubico YubiKey OTP+FIDO+CCID 0 to connect to reader at port N and check card status again with gpg --card-status
  • Enable SSH support, go to settings in Settings/Configure Kleopatra/GnuPG System/Private Keys to toggle on Enable SSH Support and Enable Putty Support.
  • Restart gpg-agent to take effect and alternatively you can manually change settings in ~/.gnupg/gpg-agent.conf if you are running on a Linux machine.
    1
    2
    gpg-connect-agent killagent /bye
    gpg-connect-agent /bye
  • Local Git configuration
    1
    2
    3
    4
    5
    # Run this command only if `gpg` commands cannot be found in the path but usually do not have to specify it after `GPG4Win` is installed correctly
    git config --global gpg.program "C:\Program Files (x86)\GnuPG\bin\gpg.exe"
    git config --global user.signingkey <KEYID>
    # Optionally, force all commits to be signed
    git config --global commit.gpgsign true
  • Test GPG signed Git commits and verified will show on each GPG signed commit. Since Git version 2.2.0 it is also possible to sign git pushes by doing git push --signed. This is used to prove the intention the author had of pushing a specific set of commits and have them become the new tip of some branch. Now if you crush down the production server with a bug in your commit, you have no excuses! Actually, git push --signed is not supported on Github yet so you still have the excuse.
    1
    2
    git tag foo-1.0 -S -m "Release 1.0 of Foo"
    git commit -S -m "Initial commit"

Configure GPG and SSH authentication in WSL2

This repo https://github.com/BlackReloaded/wsl2-ssh-pageant provides a way to connect to GPG and SSH in Windows from WSL2.

  • Install socat and ss on WSL2 with sudo apt install socat iproute2

  • Download wsl2-ssh-pageant on WSL2 and make it executable

    1
    2
    3
    4
    5
    # WSL2
    mkdir ~/.ssh
    wget https://github.com/BlackReloaded/wsl2-ssh-pageant/releases/download/v1.2.0/wsl2-ssh-pageant.exe -O ~/.ssh/wsl2-ssh-pageant.exe
    # Set it to be executable
    chmod +x ~/.ssh/wsl2-ssh-pageant.exe

  • Add the following to your shell configuration (for e.g. .bashrc, .zshrc or config.fish)

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    export SSH_AUTH_SOCK="$HOME/.ssh/agent.sock"
    if ! ss -a | grep -q "$SSH_AUTH_SOCK"; then
    rm -f "$SSH_AUTH_SOCK"
    wsl2_ssh_pageant_bin="$HOME/.ssh/wsl2-ssh-pageant.exe"
    if test -x "$wsl2_ssh_pageant_bin"; then
    (setsid nohup socat UNIX-LISTEN:"$SSH_AUTH_SOCK,fork" EXEC:"$wsl2_ssh_pageant_bin" >/dev/null 2>&1 &)
    else
    echo >&2 "WARNING: $wsl2_ssh_pageant_bin is not executable."
    fi
    unset wsl2_ssh_pageant_bin
    fi

    export GPG_AGENT_SOCK="$HOME/.gnupg/S.gpg-agent"
    if ! ss -a | grep -q "$GPG_AGENT_SOCK"; then
    rm -rf "$GPG_AGENT_SOCK"
    wsl2_ssh_pageant_bin="$HOME/.ssh/wsl2-ssh-pageant.exe"
    if test -x "$wsl2_ssh_pageant_bin"; then
    (setsid nohup socat UNIX-LISTEN:"$GPG_AGENT_SOCK,fork" EXEC:"$wsl2_ssh_pageant_bin --gpg S.gpg-agent" >/dev/null 2>&1 &)
    else
    echo >&2 "WARNING: $wsl2_ssh_pageant_bin is not executable."
    fi
    unset wsl2_ssh_pageant_bin
    fi
  • Shut down WSL2 in Windows terminal wsl.exe --shutdown and restart it again.

  • Connect to GPG and SSH from inside the WSL2 with commands ssh-add -L and gpg --card-status when yubikey is inserted. Trouble shooting: sometimes the gpg agent within linux is started and has ownership of ~/.gnupg/S.gpg-agent. Try to remove it and restart the WSL2

  • Elevate the trust level in both Windows and WSL2.

    1
    2
    3
    4
    gpg --edit-key <KEYID>
    >gpg trust # Change trust level
    >gpg 5 # Set trust level to ultimate
    >gpg save # Save the changes

Revoke your GPG key and declare on keyserver

List keys

1
gpg --list-keys

Revoke your key

1
gpg --output revoke.asc --gen-revoke key-ID

Import revocation certificate into your keyring

1
gpg --import revoke.asc

Search your key on the key-server

1
gpg --keyserver pgp.mit.edu --search-keys key-ID

Send the revoked key to the key-server

1
gpg --keyserver pgp.mit.edu --send-keys key-ID

Import keys

Don’t save your encrypted keys on keybase.io

importing public key

gpg –import my_public_key.pub

importing private key

gpg –allow-secret-key-import –import my_private_key.private

Send messages with GPG encryption

Send GPG signed emails

References