GnuPG Keys on a YubiKey

Robert S. (Robert@TryingToScale.com)
Posted on 2023 from site -> https://pages.tryingtoscale.com/OpenPGP_on_a_Yubikey.html

Keep your SSH/GPG keys safe! Protect them with an Open-PGP Card.

Download this page as an Archive file and put it on a USB drive as it's too BIG to print: GPG_YubiKey.tgz

$ sha512sum GPG_YubiKey.tgz

Verify the file output is the same as below (if so copy it to a USB drive):

7b11e870de661e887b960a99006bcc83f1c77101544907d8891311265aa70d52edde6fb2a45a1ddaf25f1b4cd7fa0d8477b6e3ed5e175749972d5bd224c18ad0 GPG_YubiKey.tgz

$ mkdir ~/Documents/GPG_guide
$ tar xvzf GPG_YubiKey.tgz -C ~/Documents/GPG_guide/

View the PDF version

$ evince ~/Documents/GPG_guide/GPG_YubiKey.pdf &

Who is this tutorial for?

System admins, developers, IT Pros, and home-lab testers.

Attack Surface

Secret keys (like a private SSH key) stored as files on your PC are a target for hackers. Maybe a Trojan was installed by mistake, or your machine was unlocked and someone jumped into a terminal or file Manager to copy your data, or they stole your Laptop. The details of how this happened is not important right now, the fact that sensitive data was stolen is and could be used to grant access to critical systems.

By using a Open-PGP Card, your data is safe as long as the card is in your possession. In order to gain access someone must touch the Open-PGP Security Key card. The contents of your GnuPG data will live inside of the card only... This way the key-file is stored in the hardware security token, and is never exposed to the internet. Almost all Open-PGP keys have two PINs — a user PIN and an administrative PIN to reset the user PIN. If you enter either or both three times incorrectly, the card will lock and you’ll need to reload from backup which is why it’s critical to have a backup.

Items you will want to have ready on hand

Before you begin this advanced tutorial, make sure you have the following (Ideally):

  1. Total USB disk drives (3)
    1. A spare small USB drive to store one Public Key File and the LUKS password file (for this one drive, it does not matter if data is already on it)... Of course, once all is done, you should put LUKS password into a Password Manager and delete the LUKS password file from this USB drive.
    2. A brand new "reliable" USB drive that has NO Data on it, to be ext4 LUKS formatted and put into a Safe Box for later storage of the archive file containing your GnuPG data Directory will ALL critical secrets in it. Do not loose, as you will need this in the future every few years to renew keys.
    3. A bootable (8GB or larger *size just for Tails only) USB drive to hold the Tails OS. If you want to store other OSes on it, get at the very least an 64GB, but I would recommend 128GB or more.
  2. A USB Hub with 4 or more ports - to make it easier to connect all these USB devices. Be sure to get the correct connectors like USB C vs. USB 3.0.
  3. Something like a Yubico YubiKey NFC 5 series Security Key that supports Smart Card (PIV). Maybe buy a spare one to have in case the first one gets lost.
  4. Optionally, A spare computer to use as a Server, for Proxmox and/or Docker. To host Gitea and/or Syncthing. Also, to be used to test OpenSSH Daemon with your new key.
  5. Your normal main online computer, to install the gpg-agent on and to connect to Servers using your brand new secure key. Hopefully, the OS is Linux, Debian/Ubuntu, or similar, so that the packages exists in your package manager. If on Windows, try WSL 2 is a new version of the Windows Subsystem for Linux. If on Mac, run Oracle VM VirtualBox https://www.virtualbox.org/wiki/Downloads.
    • For security purposes you will also use Tails for the creation of your Secret Keys.

Buy a YubiKey 5 series

Yubico’s YubiKeys are cool, they provide Universal 2nd Factor (U2F), FIDO2, One-Time-Password (OTP), and of course Smart Card (PIV) features in one device. Do not buy the cheaper ones only support FIDO, as they do not support, Smart Card (PIV)!!

I've bought a few from Amazon, but you can also buy a YubiKey 5 NFC starting price is $50 from the Yubico store. Note: YubiKey NEO only support upto 2048 bits for RSA, while the 4/5 series supports upto 4096 bits for RSA.

Ubuntu downloads

If you do not have Linux yet: Download Ubunutu Desktop from https://ubuntu.com/download/desktop, Ubuntu Server from https://ubuntu.com/download/server

Conventions used: in this tutorial I use # as a comment these things should NOT be typed out.

Notice in this tutorial I use $ as a bash command these things you are required to type out.

If you need some help with Linux basics see Linux-FYI.html as a refresher.

Creating a USB Flash disk for Tails OS

Your offline key pair must be on a "Air-Gapped" system, and use encryption on your storage device (USB drive...) in order to guard against data being stolen... If possible JUST use Tails download here [ https://tails.boum.org/install/index.en.html ] to do these steps. Remember that Tails is a secure system and all Data will be erased upon a system reboot, unless persistent storage was setup.

Tails works on most computers less than 10 years old. System requirements: 3GB RAM, 64-bit x86-64 compatible processor.

To download Balena Etcher, for creating a USB Bootable drive, see https://www.balena.io/etcher.

** It is possible, to have one USB drive that contains multiple OSes on it so, you do not need to carry around a bunch of USB boot disks. If that sounds good try out Ventoy from this link: https://www.ventoy.net/en/download.html

Booting into Tails

You are now Running "offline" (NO services running such as: - Bluetooth, WiFi, or Network card) with Tails OS on a USB drive Stick, to use while creating your highly secure GnuPG KEYS so they are not stolen by an attacker.

If you did not do the above security Step to Disable Networking, then do the following: Disconnect any LAN cable. Don't enable WiFI/Bluetooth. Disable WiFi and Bluetooth from the Settings App, Hit the Windows Key, search for Settings. Toggle both to off.

Now on this computer running the Tails OS

Make a Secure Password for GPG and LUKS

$ mkdir ~/Desktop/my_keys
$ openssl rand -base64 24 > ~/Desktop/my_keys/GPG_PWD.txt
$ openssl rand -base64 18 > ~/Desktop/LUKS_PWD.txt

Copy the ~/Desktop/LUKS_PWD.txt file to any old USB disk you have laying around so you have a way to get to your GPG data. The other file ~/Desktop/my_keys/GPG_PWD.txt will get put into an Archive file which gets put into your secure LUKS drive later in this tutorial... To read the contents of these two new files simply cat them out.

Be careful to make sure you use the correct password into the right program IE LUKS or GPG. Don't loose these, passwords!! Write them down on paper, they are large I know... Add them to a password manager as well, see: What else can I do with a Security Key -> using KeePassXC or whatever you like. Just make sure that you do not create an chicken and egg problem like your GPG Password is stored in a GPG system ;-)

$ cat ~/Desktop/my_keys/GPG_PWD.txt
$ cat ~/Desktop/LUKS_PWD.txt

Copy your password to the clipboard, and use it when prompted... To make a USB drive/stick use LUKS, open disks from Ubuntu or Tails...select the proper USB drive noted by disk Size in GB or brand name if available, then Format as New, Volume Name: My_GPG_Data, Type: Internal disk for use with Linux systems only (Ext4), Password protect volume (LUKS) encrypted, enter your secure new password from the above command... Warning: Please be sure to WIPE the correct Drive!!! For more help see [ https://tails.boum.org/doc/encryption_and_privacy/encrypted_volumes/index.en.html ]. If you already named the Volume something other than My_GPG_Data, be sure to use that in place of My_GPG_Data throughout this tutorial.

Generating an Offline Key Pair

Start off with an Empty GnuPG folder, so let's just move it out of the way.

$ mv ~/.gnupg/ ~/.gnupg_ORGINAL_$(date +"%Y-%m-%d-%H_%M_%S")/

Enter your secure password, $ cat ~/Desktop/my_keys/GPG_PWD.txt - when prompted -. 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.

Do NOT use the example Real name of: Robert Smith NOR should you use the example Email address of: robert.smith@example.com

Please use something real or easy to ID you for work.

Let's make a new master key that is only capable of certifying other keys, it should never expire.

$ gpg --expert --full-gen-key
 Please select what kind of key you want:
   (8) RSA (set your own capabilities)
Your selection? 8

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

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

Your selection? S
Your selection? E

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

Your selection? Q

RSA keys may be between 1024 and 4096 bits long.
What keysize do you want? (2048) 4096

Please specify how long the key should be valid.
Key is valid for? (0) 0
Key does not expire at all
Is this correct? (y/N) y

GnuPG needs to construct a user ID to identify your key.

Real name: Robert Smith
Email address: robert.smith@example.com
Comment:
You selected this USER-ID:
    "Robert Smith <robert.smith@example.com>"

Change (N)ame, (C)omment, (E)mail or (O)kay/(Q)uit? O

It will output they key ---

gpg: key E0B518BE7CA2EC83 marked as ultimately trusted
public and secret key created and signed.

Edit your new key and add several single-purpose subkeys, that will expire in 3 years. In the above example, the KEY-ID was E0B518BE7CA2EC83. Use YOUR KEY-ID in the line below here where it was used as a place-holder {{{KEY-ID}}}. Notice: This KEY-ID will be used a few times...so note it down.

$ gpg --expert --edit-key {{{KEY-ID}}}

Add a signature-only RSA subkey.

gpg> addkey
Please select what kind of key you want:
   (4) RSA (sign only)
Your selection? 4
RSA keys may be between 1024 and 4096 bits long.
What keysize do you want? (2048) 4096

Please specify how long the key should be valid.
Key is valid for? (0) 3y
Is this correct? (y/N) y
Really create? (y/N) y

Add an encryption-only RSA subkey.

gpg> addkey
Please select what kind of key you want:
   (6) RSA (encrypt only)
Your selection? 6
RSA keys may be between 1024 and 4096 bits long.
What keysize do you want? (2048) 4096

Please specify how long the key should be valid.
Key is valid for? (0) 3y
Is this correct? (y/N) y
Really create? (y/N) y

Add an authentication-only RSA subkey.

gpg> addkey
Please select what kind of key you want:
   (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
Your selection? E
Your selection? A

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

Your selection? Q

RSA keys may be between 1024 and 4096 bits long.
What keysize do you want? (2048) 4096

Please specify how long the key should be valid.
Key is valid for? (0) 3y
Is this correct? (y/N) y
Really create? (y/N) y

Save your changes and exit the key editing session.

gpg> save

Backup GnuPG Data

We'll need to backup the keys and subkeys in order to load the subkeys into the YubiKey. The YubiKey actually removes the subkeys from the keyring files and direclty moves them into the YubiKey. Please store these backup files as an offline copy of keys and subkeys in order to preserve them. You may be prompted for your GPG password from time to time.

The Email address is critical to ID the proper KEYs to be used, use [YOUR-GPG-EMAIL] created in step Generating an Offline Key Pair. GnuPG uses that EMAIL to construct a user ID to identify your key, it will be used a few times in this tutorial!!! So, replace the place-holder of [YOUR-GPG-EMAIL] with your email used in the Step: Generating an Offline Key Pair.

$ gpg --armor --output ~/Desktop/my_keys/public.asc --export [YOUR-GPG-EMAIL]
$ gpg --armor --output ~/Desktop/my_keys/master.key --export-secret-keys [YOUR-GPG-EMAIL]
$ gpg --armor --output ~/Desktop/my_keys/sub.key --export-secret-subkeys [YOUR-GPG-EMAIL]
$ gpg --fingerprint [YOUR-GPG-EMAIL] > ~/Desktop/my_keys/fingerprint.txt
$ gpg --gen-revoke [YOUR-GPG-EMAIL] > ~/Desktop/my_keys/revoke.asc
Revoke will output and ask for input:
Create a revocation certificate for this key? (y/N) y
Please select the reaseon for the revocation:
0 = No reason specified
1 = Key has been comromised
...
Your decision? 0
Enter an optional description; ...
> (Just hit Enter!)
Is this okay? (y/N) y

Copy the public-key-only public.asc to your regular online computer using any old USB drive that will do fine for this one.

Copy the ~/Desktop/my_keys/ to a archive file to be place into a LUKS USB drive for secure long-term storage in a safety box. You will need this LUKS USB drive with the gpg-datadir.tgz file later on in the tutorial and from time to time as your keys will expire in 3 years if you set that also when you "blow the fuse" in your Yubikey by not entering in the correct pin 3 times. You will need to redo a few steps...

Be aware that in Tails the $USER account is always amnesia and the terminal window wants to add an escape to it from $USER to the INVALID one \$USER which will always give a No such file error, this is often caused by hitting the TAB key! So be aware of that backslash issue and use $USER or just amnesia in Tails.

# Move my_keys folder into the .gnupg folder
$ mv ~/Desktop/my_keys/ ~/.gnupg/

# Make sure your in the $HOME folder
$ cd ~

# Make a compressed archive tgz file on the Desktop to be copied soon
$ tar cvzf ~/Desktop/gpg-datadir.tgz .gnupg/

# lets see if we can find your USB drives
$ ls /media/$USER
# Did you see My_GPG_Data? If so use that in the next copy command, 
# 	else use the name of your LUKS Volume

# You may do the following from a file manager, or if you would like or in the terminal:
# You should have named the drive My_GPG_Data, 
# 	copy ~/Desktop/gpg-datadir.tgz to the My_GPG_Data LUKS drive

$ cp ~/Desktop/gpg-datadir.tgz /media/$USER/My_GPG_Data/

# If that copy failed please use the File Manager as the mount point is differnt than /media/$USER/My_GPG_Data
# Here is a File Manager only if that copy FAILED
$ nautilus ~/Desktop &

If you want to verify the integrity of your backups, then delete the keys, and re-import your backed up private keys.

$ gpg --delete-secret-and-public-key [YOUR-GPG-EMAIL]
$ gpg --import ~/.gnupg/my_keys/master.key

Were done with Tails for now, so just one thing left, Verify that you can Eject your USB LUKS drive and reconnect and enter the password to make sure it Worked! Then Open the archive in the file manager gpg-datadir.tgz does it have folders and files in it? If so, let's move on...

Power off Tails OS


Working on your main or "Online" Ubuntu/Debian computer

Installing the Required Linux Software

Install the required GnuPG, Smart Card, and YubiKey packages. Needed on the "Online" Ubuntu/Debian based computer only, but not on any Server system, nor on the "Offline" computer either! You must become root to install packages...

$ sudo -i
$ apt-get update
$ apt-get install pcscd opensc 
$ apt-get install gnupg gpg gpg-agent scdaemon
$ apt-get install yubikey-manager 
$ apt-get install libpam-yubico libpam-u2f libu2f-udev
$ exit

Configuring the scdaemon

Same as above: do this step only on the Online Ubuntu systems but not on any server system, or the offline Tails computer.

$ nano ~/.gnupg/scdaemon.conf
# After X seconds of inactivity shutdown PIV
# User must re-enter PIN to use PIV
card-timeout 900  # 15 minutes.

# disable-ccid, allows using pcsc security ACL
# - which will disable the integrated support with CCID compliant readers.
disable-ccid
[ ctrl+o to save and ctrl+x exit ]

So, you now have 15 minutes to relogin without needing to enter in a PIN# or touch the key. You may want to reduce that timeout to a few minutes if paranoid. I think it's a good timeout as you can just pull the key out and no one will be able to login to another of your protected systems.

Harden YubiKey OpenPGP Configuration

Insert your YubiKey.

***ONLY RUN THE FOLLOWING IF YOUR PIN IS LOCKED AND THE SMART CARD IS UNUSABLE***:

# Danger: This will erase and Factory reset the PIV, 
# So ONLY use if Locked out (no tries LEFT) and have a Backup!
$ gpg --edit-card
gpg/card> admin
gpg/card> factory-reset

# If you've completed this tutorial before, 
# you'll need to redo step #9 in Tails: 
# Changing your YubiKey PINs,
# Importing GnuPG Keys, and Move Subkeys into the YubiKey.
# 
# You will propbly also need to do step 
# 10.1 Import GnuPG stubed Keys for YubiKey to Work now
# on your main Online PC.
#
# If Touch is not working...in Ubuntu redo the next step
# 8.4 Force on YubiKey Touch for security.

Force on YubiKey Touch for security

The three-letter parameters are short for (enc)ryption, (sig)nature, and (aut)hentication. This configuration will prevent remote attackers from using your Open-PGP card as you need physical access to it to touch the button on the key to use it.

$ ykman openpgp keys set-touch enc On
$ ykman openpgp keys set-touch sig On
$ ykman openpgp keys set-touch aut On

Check the current settings with the following command.

$ ykman openpgp info

Booting into Tails again

Changing your YubiKey PINs

Connect your YubiKey to your computer and edit the OpenPGP card settings.

$ gpg --card-edit

Most commands we will use in this session are not available until after the admin command is executed. Type help to get assistance if needed.

Whenever you see the gpg/card> prompt, list will output the OpenPGP card settings, again if stuck help will show the commands you may use.

gpg/card> admin
Admin commands are allowed

The YubiKey’s default user PIN is 123456, the default admin PIN is 12345678, and the default reset PIN is never set. You will want to resetup these PINs. Be sure that you can memorize these PINS as you only get 3 chances before the Security Key destroys your data, then you will need to restore from backups and repeat these steps. The new admin PIN can contain letters and numbers - it must be longer than 8 characters long.

gpg/card> passwd

1 - change PIN
2 - unblock PIN
3 - change Admin PIN
4 - set the Reset Code
Q - quit

Your selection? 1

Your selection? 3

Your selection? 4

Your selection? Q

You might want to require a signature PIN. The forcesig command allows you to toggle this, so check that the setting is correct with list command after you toggle that.

gpg/card> forcesig

gpg/card> list
Signature PIN ....: forced

You may setup the OpenPGP card with your name, sex, preferred language, and so on...

gpg/card> name
Cardholder's surname: Smith
Cardholder's given name: Robert

gpg/card> lang
Language preferences: en

When done, type quit.

gpg/card> quit

Importing GnuPG Keys

Insert your LUKS encrypted USB disk.

$ cd ~
$ mv .gnupg/ .gnupg_ORIGANL_$(date +"%Y-%m-%d-%H_%M_%S")/

# Let's see what USB drives are mounted, is My_GPG_Data shown?
$ ls /media/$USER

# Was it called something else? If so, use that instead of:
# 	My_GPG_Data in the next copy command

# In the next copy command be sure to include the dot at the end,
# 	as it means to put the file in your current folder
$ cp /media/$USER/My_GPG_Data/gpg-datadir.tgz .

# If the above command fails to copy, just use your File Manager to copy over
# gpg-datadir.tgz from the LUKS USB disk to the root of your Home folder!

# Lets extract the compressed tar file (it should go into ~/.gnupg/ on its own)
$ tar -xzf gpg-datadir.tgz

# If it extracted okay, you will see gpg sub keys listed after this command
$ gpg --list-secret-keys

# next copy the output of your GPG_PWD.txt file into the clipboard for use in a moment
$ cat .gnupg/my_keys/GPG_PWD.txt

Move Subkeys into the YubiKey

Insert your Yubikey now.

Here we will modify your key to move subkeys from your keyring to the YubiKey. This is a destructive one way operation, only do this on a copy of your gnupg directory as it will erase the keys from the gnupg folder keyring and create a link or stub to the YubiKey.

$ gpg --expert --edit-key [YOUR-GPG-EMAIL]

Moving your signature-only subkey to the YubiKey’s signature key slot.

gpg> help
gpg> key 1
gpg> keytocard
Please select where to store the key:
   (1) Signature key
   (3) Authentication key
Your selection? 1
gpg> key 1

Moving your encryption-only subkey to the YubiKey’s encryption key slot.

gpg> key 2
gpg> keytocard
Please select where to store the key:
   (2) Encryption key
Your selection? 2
gpg> key 2

Moving your authentication-only subkey to the YubiKey’s authentication key slot.

gpg> key 3
gpg> keytocard
Please select where to store the key:
   (3) Authentication key
Your selection? 3
gpg> key 3

Save these changes and quit the key editing session.

gpg> save
$ gpg --card-status
$ gpg --list-secret-keys
The output should show: ssb> The > means not on the computer, but kept on external USB
device! Cool!!!

All done...Power off Tails!


On your main/Online Ubuntu Computer - add GPG Support

Import GnuPG stubed Keys for YubiKey to Work now!

In Step: Backup GnuPG Data you should have Copied public.asc to a USB drive.

Now copy that file over to the Desktop, so we can Import the stubed Key back in. If you forgot were it is, use your LUKS USB drive, untar the archive file into the Desktop and go into my_keys folder, the public.asc file is there, ONLY extract that one file!

After the file has been copied, you may eject that drive, so you can Insert your YubiKey.

$ gpg --list-secret-keys
# output should be blank from the above command
$ gpg --import ~/Desktop/public.asc
$ gpg --card-status
# note this time the command list-secret-keys should return ssb> data
$ gpg --list-secret-keys

House keeping you may delete the public.asc file now $ rm ~/Desktop/public.asc

Better ciphers for GnuPG encryption/signing

Lets setup gnupg to use good ciphers...these will be using during encryption and signing processes

$ nano ~/.gnupg/gpg.conf
# Use UTF-8 character encoding everywhere.
display-charset utf-8
utf8-strings

# Use GnuPG Agent (gpg-agent) for secret key management.
use-agent

# Don't leak comments or software version information.
no-comments
no-emit-version

# Display full fingerprints.
keyid-format long
with-fingerprint

# Default key to use since more than one private key is in the keyring.
# Get public key ID with: gpg --list-secret-keys
#default-key XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
default-recipient-self

# When verifying a signature made from a subkey, require that the
# cross-certification "back signature" on the subkey is present and valid.
require-cross-certification

# Prefer the strongest ciphers and digests in the OpenPGP specification.
# To list available algorithms: gpg --version
personal-cipher-preferences AES256 AES192 AES
personal-digest-preferences SHA512 SHA384 SHA256 SHA224
personal-compress-preferences BZIP2 ZLIB ZIP Uncompressed

# Use the strongest digest when signing a key.
cert-digest-algo SHA512

default-preference-list AES256 AES192 AES SHA512 SHA384 SHA256 SHA224 BZIP2 ZLIB ZIP Uncompressed
[ ctrl+o to save and ctrl+x exit ]

Setup GPG Client for SSH

$ nano ~/.gnupg/gpg-agent.conf and verify ssh-agent support is set to [enable-ssh-support].

# Set number of seconds for which cache entries are valid.
default-cache-ttl       300  #  5 minutes.
default-cache-ttl-ssh   300  #  5 minutes.
max-cache-ttl           900  # 15 minutes.
max-cache-ttl-ssh       900  # 15 minutes.

enable-ssh-support # Enable OpenSSH Agent (ssh-agent) protocol support.
write-env-file ~/.gpg-agent-info
[ ctrl+o to save and ctrl+x exit ]

Still on your main/Online Ubuntu Computer - Add OpenSSH Support

Setup SSH client for Security

$ nano ~/.ssh/config

Host *
    Protocol 2
    HostKeyAlgorithms sk-ssh-ed25519@openssh.com,ssh-ed25519,rsa-sha2-512,rsa-sha2-256,ssh-rsa
    KexAlgorithms curve25519-sha256,curve25519-sha256@libssh.org,diffie-hellman-group18-sha512,diffie-hellman-group16-sha512
    Ciphers chacha20-poly1305@openssh.com,aes256-gcm@openssh.com,aes128-gcm@openssh.com,aes256-ctr,aes192-ctr,aes128-ctr
    MACs hmac-sha2-512-etm@openssh.com,hmac-sha2-256-etm@openssh.com,hmac-sha2-512,hmac-sha2-256
    StrictHostKeyChecking ask
    VerifyHostKeyDNS ask
    User root
    Port 22
    ServerAliveInterval 300
    ServerAliveCountMax 3
    ForwardAgent no
    ForwardX11 no
    ForwardX11Trusted no
    PermitLocalCommand no
    HashKnownHosts yes
    TCPKeepAlive yes
    SendEnv LANG LC_*
[ ctrl+o to save and ctrl+x exit ]

$ nano ~/.profile verify that ssh is setup for the gpg-agent in place of the existing ssh-agent.

if [ -z "$SSH_AUTH_SOCK" ]; then
    export SSH_AUTH_SOCK="$(gpgconf --list-dirs agent-ssh-socket)"
fi
[ ctrl+o to save and ctrl+x exit ]

GPG seems to output pin-entry process onto some other external source and not the current terminal being used. TTY holds the ref to the current terminal and thus exporting it as GPG_TTY solves the problem in this case. Add the following to your ~/.bashrc and ~/.zshrc so that a required environment variable will be set per-shell.

$ nano ~/.bashrc

export GPG_TTY=$TTY
[ ctrl+o to save and ctrl+x exit ]

Kill any running gpg-agent and ssh-agent processes your user has open so that a the new gpg-agent loads.

$ killall -u ${USER} ssh-agent gpg-agent

Log out and log back in so the session environment variables required for ssh will use gpg-agent now in place of the ssh-agent. Check that gpg can still read your YubiKey, which has verifies the gpg-agent is running.

$ gpg --card-status

Now, ssh should require a touch to authenticate on the key slot of your YubiKey as an SSH authentication key.

This next command will get the SSH-formatted public key from the YubiKey. Copy the public key you now have into ~/.ssh/authorized_keys on the servers/systems you wish to control/use. You may also add this public key with SSH services such as GitLab, GitHub, etc...

$ ssh-add -L

Make certian that the correct key is listed, it should end with a card number comment that contains the serial number of this YubiKey.

Output from above: ssh-rsa ... cardno:####Serial No. here####

Congratulations, you have a YubiKey useful for SSH public key authentication.

Upload your new Public Key to a Server

$ ssh-copy-id user@IP_of_Your_Server

If that did not work you can try the next way, the harder method...

Uploading Public Keys the hard way

$ ssh USER@IP_Of_Server_Here

# Become ROOT
$ sudo -i
$ cd /home/[USERNAME]
$ mkdir .ssh
$ chmod 700 .ssh
$ chown [USERNAME]:[USERNAME] .ssh
$ cd .ssh
$ nano authorized_keys
[[Paste in Public SSH Key here]]
ctrl+x to save and exit

$ chmod 600 authorized_keys
$ chown [USERNAME]:[USERNAME] authorized_keys
exit
exit

You did it! You have now completed and finished all that was needed to setup GnuPG Keys on a YubiKey.

Make your server only uses Keys

This section is for Server Administrators only: ssh_server_lockdown.html


****The next 2 steps (#12 Uploading & #13 Downloading) I skip, as I do not need to exchange keys...this way****

Uploading your Public Key to Keyservers

You should be ready now to upload your public key and subkeys to the keyservers.

$ gpg --send-keys {{{KEY-ID}}}

Pick a keyserver such as keys.openpgp.org, to verify each email address by which your public key should be searchable. When desired run the following command:

$ gpg --export [YOUR-GPG-EMAIL] | curl -T - https://keys.openpgp.org/

Ok, a URL will be displayed from the output of the last command. Put that into your web browser of choice and do as it suggests...to the ID verification page.

Here is a link about how all this works https://keys.openpgp.org/about and if you are concerned about privacy see the privacy link on that about page.

Downloading Public Key from Keyserver

Get your public key that you put on to the keyservers. After that plug in the YubiKey and check the YubiKey’s card status. Does everything match up? If, so Cool!

$ gpg --recv-keys  {{{KEY-ID}}}
$ gpg --card-status

What else can I do with a Security Key?

Short Answer is setup KeePassXC [https://keepassxc.org/] a Password Manager, to use your YubiKey! Note this is by default install in Tails OS.

First let's setup the YubiKey on your main Online Ubuntu computer.

Info about the YubiKey Manager from [ https://www.yubico.com/support/download/yubikey-manager/ ].

# Install wget to download yubikey-manager AppImage file.
$ sudo apt install wget
$ wget -O yubikey-mgr.AppImage https://developers.yubico.com/yubikey-manager-qt/Releases/yubikey-manager-qt-latest-linux.AppImage
$ chmod +x yubikey-mgr.AppImage
$ ./yubikey-mgr.AppImage

Now goto Applications, OTP (One-Time Password), Long Touch (Slot 2), click Configure: Challenge-response, Generate a Secret Key [Make sure to backup this Key using a scrap paper, then put it in a safe], now enable Require Touch, then click Finish. You can later on, use this Secret Key again on another Security Key as a Backup...

Here let's Talk about what we should Setup: 
In KeePassXC, Enable a Password, Enable a Key File 
(do not put it in the same directory as the database file), 
Enable YubiKey Challenge-Response on Slot 2. 
Under Advanced Encryption, Encryption Algorithm: AES 256-bit, 
Key Derivation Function: Argon2d (KDBX 4 - recommended).
Let's do this: Open KeePassXC, Click Create a new Database.

Replace Robs with Your Name...

Database Name: Robs_Work_Passwords
Description: Company XYZ
Click Continue. Encryption Settings: The default is good: KDBX 4.0 (Recommended),
Click Continue. Database Credentials: Enter a Strong Password, Confirm it. 
Click Add additional protection...
Click Add a Key File, click Generate. Give it a name 
(set the path to /home/[SYSTEM-USERNAME-HERE]/keys): Robs_Work_Passwords.key
Click Save. Click Add YubiKey Challenge-Response. 
Make sure your YubiKey is selected.
Click Done. Give it a file name 
(set the path to /home/[SYSTEM-USERNAME-HERE]/passwords): Robs_Work_Passwords.kdbx
Click Save.

Add a new Entry to the password manager for Test site/system, Testing User, and Testing123 Password. Make and verify, file permission only allow your user (Read/Write) access to these files and are not accessable by other users on the system! Here is an example of that:

$ chmod 600 ~/passwords/Robs_Work_Passwords.kdbx
$ chmod 600 ~/keys/Robs_Work_Passwords.key

Close out of KeePass XC and re-open it. Can you still access the Test entry you just made? If, so move one to the next optional steps, which will require a spare computer like an old laptop to use as a server, I use a hypervisor called Proxmox [https://www.proxmox.com/en/downloads], but you do not have to. Be aware, that Proxmox will erase all of your information in order to complete the install!! Proxmox system requiements: https://www.proxmox.com/en/proxmox-ve/requirements.

Now, that you are syncing passwords, try to add another test entry to the system. Can you see this new entry on the other computers? If so, go ahead now and add all your passwords.

Always, backup your Password Database and KEY files to a ext4 formatted LUKS encrypted USB Drive, so you do not get locked out of all of the systems it keeps track of. You should also export to CSV file format so you can import the data on anything later on, however, be very careful to make sure that it is moved to the Encrypted drive and does not exist on your local filesystem! So, save it to the ext4 drive not on your local PC. Verify that the CSV file is not on your computer. To keep a Printable Copy of All your Systems and Passwords Export to an HTML file, then open it with a web browser, so you may Print it out. Be very sure, that file too exists only on the ext4 Encrypted LUKS USB drive! Put all of this into a Safety Box!


Trust your-own GPG Key

Before you are able to use your gnupg key with encryption, it must be marked as trusted!

$ gpg --edit-key [YOUR-GPG-EMAIL]
gpg> trust
You will be asked to select the trust level from the following:

1 = I don't know or won't say
2 = I do NOT trust
3 = I trust marginally
4 = I trust fully
5 = I trust ultimately
m = back to the main menu
I selected 5 since I created the key so of course I trust it ultimately :). 
It will ask you to confirm your decision:

Your decision? 5
Do you really want to set this key to ultimate trust? (y/N) y
After confirming, quit with:

gpg> quit
You should then be able to encrypt using that key.

Using gpg to encrypt/decrypt files

------------------Using GPG----------------------------
Method A - sign: 
(Sign a File:) $ gpg --sign doc.txt
(Verify file:) $ gpg --verify doc.txt.gpg

# Remember that the end user needs your Public Key to verify files!!!
Method B - clear sign:
(Sign a File:) $ gpg --clear-sign doc.txt
(Verify file:) $ gpg --verify doc.txt.asc

=======To Encrypt a File:
$ gpg -r [YOUR-GPG-EMAIL] --encrypt doc.txt
=======To Decrypt or Decode/un-encrypt the File:
$ gpg --decrypt doc.txt.gpg > document.txt

About Methods A and B... Signing files....the advantage of using gpg --clearsign is that the signed document and the signature are combined into a single file, which can be convenient for sending or storing the document. However, the disadvantage is that the signature can be modified along with the original document, since it is included inline.

On the other hand, gpg --sign creates a separate signature file, which allows the original document to remain unchanged and ensures that the signature cannot be tampered with. The disadvantage is that the signed document and signature are two separate files, which can be less convenient in some cases.

Also, note that the end user needs your Public Key in order to verify the files...There are a few ways that end users can import your public key:

From a keyserver: If you upload your public key to a keyserver, end users can search for and import it directly from the keyserver using GnuPG. They can run the command gpg --search-keys to search for your key and then run gpg --recv-keys to import it.

From a file: If you distribute your public key as a file, end users can import it by running the command gpg --import in their terminal. This will import your public key into their keyring.

From an email: If you send your public key to an end user via email, they can import it by saving the key as a file and then running the gpg --import command on the file.

It's important to note that end users will need to verify that the public key they import actually belongs to you. They can do this by verifying the key's fingerprint or by checking the key's signature chain to ensure that it has been signed by a trusted key.

Pass is (the standard UNIX password manager).

--------------------Using PASS--------------------------
Now let’s install PASSword manager.
$ sudo apt update
$ sudo apt install pass

$ gpg --list-key

Copy the fingerprint below pub [C]

$ pass init "[Paste in that fingerprint HERE.]"


To add a password: $ pass insert email/myserver22

To see all: $ pass

To view a password: $ pass email/myserver22

To copy it to the clipboard: $ pass -c email/myserver22

To store multiple lines of text: $ pass -m sites/linode

{{The first line is the password, next lines maybe username, etc...}}

Please NOTE: Data is stored in: ~/.password-store

How to Manually add an entry without pass:
$ mkdir ~/.password-store/btc
$ cd ~/.password-store/btc
$ nano bitcoin1
$ gpg -r [YOUR-GPG-EMAIL] --encrypt bitcoin1

My Keys have Expired now what?

To renew your keys follow these steps renew_keys.html