echjansen / pure-security

Guides and scripts to make your daily life more secure. Included are support for GnuPG, GPG, OnlyKey and YubiKey.

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

=== P U R E - S E C U R I T Y ===

This repository contains usefull information and scripts to enable security on (Arch) Linux systems. Assuming that you are setting up security from scratch the following steps would be common to execute:

  1. Create GPG keys
  2. Create a backup of GPG keys on an external USB storage device
  3. Restore GPG keys from an external storage device
  4. Move the private GPG keys to an external YubiKey device, or
  5. Move the private GPG keys to an external OnlyKey device

Although the scripts are developed and tested on Arch Linux, they should work on other Linux distributions.

ScriptDescription
gpg-provisionCreate a new set of GPG keys with [C] Certicate master and [S] Sign, [E] Encrypt and [A] Authenticate subkeys.
gpg-backup-to-usbCreate a USB backup for the GnuPG key chain (LUKS) and public keys.
gpg-restore-from-subRestore the USB backup created with ~gpg-backup-to-usb.
onlykey-wipeClear all RSA and ECC registers on OnlyKey device.
onlykey-provisionTransfer subkeys (created with gpg-provision) to OnlyKey device.

For more information on OnlyKey check these OnlyKey notes. For more information on YubiKey check these YubiKey notes. For more information on Security protocols check these Protocol notes.

Installation Process

Assuming that you have no GPG keys this description walks you through the process of:

  1. Creating a GPG key pair
  2. Back-up the GPG key pair to a USB storage device
  3. Restoring the GPG key pair from a USB storgae device
  4. Installing GPG keys on OnlyKey device, and / or
  5. Installing GPG kyes on YubiKey device

The scripts in this repository will assist you with the required tasks.

Prerequisites

When creating and transfering GnuPG keys, you are handling secret information. It is therefor best to execute the commands and scripts on a trusted system. A trusted system would not be connected to the internet when handling GnuPG keys. It is assumed you installed Arch Linux in a virtual environment (see pure-arch for a secure Arch Linux installation script).

Once booted in an Arch Linux environment install the Linux packages for GnuPG key creation and USB backup:

pacman -Sy                      # update the pacman catalog
pacman -S git gnupg             # install git and gnupg packages
git clone https://github.com/echjansen/pure-security

The following is required for OnlyKey hardware tokens:

pacman -S python-setuptools libusb python-pip libfido2
pacman -S python-pgpy python-ptyprocess
pip install onlykey             # onlykey client tool
pip intsall onlykey-agent       # onlykey agent

Linux system requires a special rule for non-root users to use USB devices.

curl -o 49-onlykey.rules https://raw.githubusercontent.com/echjansen/main/config/49-onlykey.rules
sudo cp 49-onlykey.rules /etc/udev/rules.d/
sudo udevadm control --reload-rules
sudo udevadm trigger
# unplug and plug in OnlyKey device

Scripts

gpg-provision

Usage:

./gpg-provision.py

This scripts provisions a new GPG Key-chain according to best practices with the [C] Certify key on the Master key and [S][E][A] on sub-keys. The script configures the keychain in a /tmp directory, rather than in the default /.gnupg. The created GnuPG key-chain can then be:

  1. Taken offline for secure storage (USB) - see gpg-backup-to-usb
  2. Transfered to a smartcard such as OnlyKey (see onlykey-provision) or YubiKey

Output:

# ============================================================
# Create new GPG key pair.
# Inlcudes a Master [C] and subkeys [S][E][A]
# ============================================================
# Real Name: user
# Email: user@domain.com
# Please provide a password to protect the secret key chain:
# Please repeat the password:
# The password provided is very short. Do you wish to continue (y/n)?y
# 1. Curve 25519 (default), 2. RSA: 1
# Expiration in years (2y): 2y

# ============================================================
#  Selected values for GPG Key creation:
# ============================================================
#  GNUPGHOME:  /tmp/gpg_ajttd1g3
#  IDENTITY:   "user <user@domain.com>"
#  KEY TYPE:   25519
#  EXPIRATION: 2y
# Continue (y/n)?y

# gpg: keybox '/tmp/gpg_ajttd1g3/pubring.kbx' created
# gpg: /tmp/gpg_ajttd1g3/trustdb.gpg: trustdb created
# gpg: directory '/tmp/gpg_ajttd1g3/openpgp-revocs.d' created
# gpg: revocation certificate stored as '/tmp/gpg_ajttd1g3/openpgp-revocs.d/95D2F7D300BF2DDA30CD217C586757876553EB4C.rev'
# gpg: checking the trustdb
# gpg: marginals needed: 3  completes needed: 1  trust model: pgp
# gpg: depth: 0  valid:   1  signed:   0  trust: 0-, 0q, 0n, 0m, 0f, 1u

# ============================================================
#  Keys created and keys exported for backup
#  Check GPG_GNUPGHOME for backup files.
# ============================================================
# /tmp/gpg_ajttd1g3/pubring.kbx
# -----------------------------
# sec   ed25519/0x586757876553EB4C 2024-06-14 [C]
#       Key fingerprint = 95D2 F7D3 00BF 2DDA 30CD  217C 5867 5787 6553 EB4C
# uid                   [ultimate] user <user@domain.com>
# ssb   ed25519/0x525446A57AA572A2 2024-06-14 [S] [expires: 2026-06-14]
# ssb   cv25519/0x92B2CDB6AB2377E1 2024-06-14 [E] [expires: 2026-06-14]
# ssb   ed25519/0xBA403E26A834F226 2024-06-14 [A] [expires: 2026-06-14]

gpg-backup-to-usb

Usage:

./gpg-backup-to-usb.py [-h] usb gnupghome pubkey

Backup GnuPG private and public keys to USB backup drive.

This script requires three argumenents.

  1. The connected USB device in sdx format. Use the lsblk command to list available USB devices.
  2. The full path to the GnuPG keychain is stored ($GNUPGHOME).
  3. The full path to the public key in armored format public-key.asc.

This script must be executed as root sudo gpg-backup. Only run this on a secure and trusted system.

positional arguments: usb USB device in sdx format gnupghome path to the GnuPG path pubkey Public key exported using ~ gpg -a –export public.asc

options: -h, –help show this help message and exit

Backup GnuPG keys to USB device example: sudo ./gpgbackup.py sda $GNUPGHOME public.asc

Output:

# =====================================================
#  Backup GnuPG Key-chain to USB Drive:
# =====================================================

# All data on /dev/sdb will be deleted. Continue (y/n)?y
# Please provide a password to protect the secret key partition:
# Please repeat the password:
# The password provided is very short. Do you wish to continue (y/n)?y

# Archiving GNUPGHOME in LUKS partition on USB.
# =============================================
# [ * ] Creating new partition table for: /dev/sdb
# [ * ] Creating partition: /dev/sdb1
# [ * ] Creating LUKS partition: /dev/sdb1
# [ * ] Opening LUKS partition: SECRET
# [ * ] Formatting partition: /dev/mapper/SECRET
# [ * ] Removing folder: /mnt/secret
# [ * ] Creating folder /mnt/secret
# [ * ] Mounting partition: /dev/mapper/SECRET to /mnt/secret
# [ * ] Copying folder from: /tmp/gpg_mxxn633x/ to /mnt/secret
# [ * ] Unmounting partition: /mnt/secret
# [ * ] Removing folder: /mnt/secret
# [ * ] Closing LUKS partition: /dev/mapper/SECRET

# Copying GNUPG public key to partition on USB.
# =============================================
# [ * ] Creating partition: /dev/sdb2
# [ * ] Formatting partition: /dev/sdb2
# [ * ] Creating folder /mnt/public
# [ * ] Mounting partition: /dev/sdb2 to /mnt/public
# [ * ] Copying file from: /tmp/gpg_mxxn633x/1C68B003C941458B.public.key.asc to /mnt/public
# [ * ] Unmounting partition: /mnt/public
# [ * ] Removing folder: /mnt/public

# =====================================================
#  GPG Key Backup to USB Drive completed successfully.
# =====================================================
# Remove the USB device, and store it in a save location.
# The USB contains two partitions:
# 1. /dev/sdb1 - The secret LUKS partition that contains the complete GNUPGHOME content and exported key files.
# 2. /dev/sdb2 - The public partition also contains the scripts in case a reverse engineering is required.

gpg-restore-from-usb

This script assists in restoring GnuPG private and public keys from USB backup drive, created with gpg-backup-to-usb.

Once the gpg-restore-from-sub script has been executed the secret and public partitions on the backup USB have been mounted, and are accessible on /mnt/public for the public keys, and /mnt/secret for the private keys.

To restore the keychain, configuration, and trusted keys:

rm ~/.gnupg/                          # Remove the old keychain.
cp -r /mnt/secret/gpg_xxx ~/.gnupg    # Copy the stored keychain and configuration
gpg --list-secret-keys                # Validate if the GnuPG keychain is correct.
sudo reboot now                       # Reboot

To restore the keychain only - follow the following procedure:

rm ~/.gnupg/                          # Remove the old keychain.
gpg -k                                # Innitiate the gpg keychain.
gpg --import xxxx.public.key.asc      # Import the public keys from ~/mnt/secret~
gpg --import xxxx.private.master.asc  # Import the private keys from ~/mnt/secret~
gpg --list-secret-keys                # Validate if the GnuPG keychain is correct.
gpg --edit-key <KEY-ID>               # Edit the key and set the trust level to 5.
> trust
> 5
sudo reboot now                       # Reboot

usage:

gpg-restore-from-usb.py [-h] usb

usage: gpg-restore-from-usb.py [-h] usb

Restore the GnuPG private and public keys from USB backup drive.

This script requires one argumenent.

  1. The connected USB device in sdx format. Use the lsblk command to list available USB devices.

This script must be executed as root sudo ./gpg-restore-from-usb.py. Only run this on a secure and trusted system, like a live Arch Linux ISO.

positional arguments: usb path to the USB device in sdx format

options: -h, –help show this help message and exit

Restore GnuPG keys from USB device example: sudo ./gpg-restore-from-usb.py sda

script output:

# ================================================================
#  Restore GnuPG Key-chain from USB Drive:
# ================================================================
# Note: you likely want to execute this script on a Live Arch ISO!
# Please provide the password to unlock the secret partition:
# [ * ] Opening LUKS partition: SECRET
# [ * ] Creating folder /mnt/private
# [ * ] Mounting partition: /dev/mapper/SECRET to /mnt/private
# [ * ] Copying folder from: /mnt/private to /tmp/gpg_418qjzms
# [ * ] Unmounting partition: /mnt/private
# [ * ] Removing folder: /mnt/private
# [ * ] Closing LUKS partition: /dev/mapper/SECRET

# =====================================================
#  Restore of GPG Key Backup from  USB completed.
# =====================================================
# Remove the USB device, and store it in a save location.
# a. The GnuPG key has been restored to: /tmp/gpg_418qjzms
# b. It might be required to take ownership if the secret partition with: sudo chown -R user:user ~/tmp/gpx_xxxxx~

# You have now several options of using the restored gpg data:
# 1. Import the secret keys on the harddrive (not recommended) with: ~gpg --import /tmp/gpg_xxx/xxx.private.subkeys.asc~
# 2. Move the imported secret keys to a YubiKey, or
# 3. Move the imported secret keys to an OnlyKey
# 4. Reboot the machine to remove all data.

onlykey-wipe (optional)

This script wipes all existing GPG - ECC (16) / RSA (4) keys from OnlyKey.

usage:

./onlykey-wipe.sh

script output:

# Successfully wiped ECC Key
# Successfully set Label
# Successfully wiped ECC Key
# Successfully set Label
# Successfully wiped ECC Key
# Successfully set Label
# Successfully wiped ECC Key
# Successfully set Label
# Successfully wiped ECC Key
# Successfully set Label
# Successfully wiped ECC Key
# Successfully set Label
# Successfully wiped ECC Key
# Successfully set Label
# Successfully wiped ECC Key
# Successfully set Label
# Successfully wiped ECC Key
# Successfully set Label
# Successfully wiped ECC Key
# Successfully set Label
# Successfully wiped ECC Key
# Successfully set Label
# Successfully wiped ECC Key
# Successfully set Label
# Successfully wiped ECC Key
# Successfully set Label
# Successfully wiped ECC Key
# Successfully set Label
# Successfully wiped ECC Key
# Successfully set Label
# Successfully wiped ECC Key
# Successfully set Label
# Successfully wiped RSA Private Key
# Successfully set Label
# Successfully wiped RSA Private Key
# Successfully set Label
# Successfully wiped RSA Private Key
# Successfully set Label
# Successfully wiped RSA Private Key
# Successfully set Label

onlykey-provision

This script transfers private subkeys to OnlyKey. If OnlyKey has already keys loaded, the script will strore the new sub-keys in the next available slots (there are 16 slots in total available for GPG keys). Alternatively, any pre-programmed keys can be wirped with the onlykey-wipe script.

usage:

./onlykey-provision.py -d private-subkey.asc # Dryrun
./onlykey-provision.py private-subkey.asc    # Transfer private keys

usage: onlykey-provision.py [-h] [-d] [–no-expired] [–no-colors] [-p PASSPHRASE] keyfile

Extract secret subkeys from a OpenPGP key.

This script will display and set the raw private keys and subkeys on your OnlyKey. Only run this on a secure trusted system.

positional arguments: keyfile path to the secret PEM-encoded key file, or ‘-’ for stdin.

options: -h, –help show this help message and exit -d, –display display only, extracted keys shown for loading in the OnlyKey Desktop App –no-expired do not show expired subkeys –no-colors do not output with colors. Usefull for piping output and use in scripts. -p PASSPHRASE, –passphrase PASSPHRASE the passphrase of the key. Don’t forget bash’s history keeps everything !

Extract and load keys onto OnlyKey example: gpg –export-secret-keys -a keyid | ./onlykey-cli-gpg-add-keys - yubikey.org ~/mykey.asc –no-expired Extract and display for loading in the OnlyKey Desktop App example: ./onlykey-cli-gpg-add-keys ~/mykey.asc -d

script output:

# =====================================================
# | OnlyKey Provisioning script                       |
# =====================================================
# Enter GPG key password to open key:
# No secret primary key

# Extracting subkeys...
# subkey id: XXXXXXXXXXXXXXXX
# subkey type: EdDSA
# subkey usage: S
# subkey size: 256 bits

# subkey id: XXXXXXXXXXXXXXXX
# subkey type: ECDSA
# subkey usage: E
# subkey size: 256 bits

# subkey id: XXXXXXXXXXXXXXXX
# subkey type: EdDSA
# subkey usage: A
# subkey size: 256 bits


# Keys without a private key:
# keyid: b'XXXXXXXXXXXXXXXX', type: b'cESCA', algorithm: 22, keylength b'255'

# Keys not supported:
# keyid: b'XXXXXXXXXXXXXXXX', type: b'a', algorithm: 22, keylength b'255'

# Keys to create:

# Transfering keys ...
# b's'
# only_key.setkey(101, 'x', 's', 'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx')
# Successfully set ECC Key
# only_key.setslot(29, MessageField.LABEL, XXXXXXXXXXXXXXXX)
# Successfully set Label
# b'e'
# only_key.setkey(102, 'x', 'd', 'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx')
# Successfully set ECC Key
# only_key.setslot(30, MessageField.LABEL, XXXXXXXXXXXXXXXX)
# Successfully set Label

# Keyslots:
# <Slot 'RSA Key 1|b'''>
# <Slot 'RSA Key 2|b'''>
# <Slot 'RSA Key 3|b'''>
# <Slot 'RSA Key 4|b'''>
# <Slot 'ECC Key 1|b'XXXXXXXXXXXXXXXX''>
# <Slot 'ECC Key 2|b'XXXXXXXXXXXXXXXX''>
# <Slot 'ECC Key 3|b'''>
# <Slot 'ECC Key 4|b'''>
# <Slot 'ECC Key 5|b'''>
# <Slot 'ECC Key 6|b'''>
# <Slot 'ECC Key 7|b'''>
# <Slot 'ECC Key 8|b'''>
# <Slot 'ECC Key 9|b'''>
# <Slot 'ECC Key 10|b'''>
# <Slot 'ECC Key 11|b'''>
# <Slot 'ECC Key 12|b'''>
# <Slot 'ECC Key 13|b'''>
# <Slot 'ECC Key 14|b'''>
# <Slot 'ECC Key 15|b'''>
# <Slot 'ECC Key 16|b'''>

About

Guides and scripts to make your daily life more secure. Included are support for GnuPG, GPG, OnlyKey and YubiKey.

License:GNU General Public License v3.0


Languages

Language:Python 97.8%Language:Shell 2.2%