diff --git a/README.md b/README.md index deec54d..3ffcdbf 100644 --- a/README.md +++ b/README.md @@ -29,15 +29,11 @@ If you have a comment or suggestion, please open an [issue](https://github.com/d * [Encryption](#encryption-1) * [Authentication](#authentication-1) - [Verify card](#verify-card) -- [Export public key](#export-public-key) - [Cleanup](#cleanup) - [Using keys](#using-keys) - [Import public key](#import-public-key) * [Trust master key](#trust-master-key) - [Insert YubiKey](#insert-yubikey) -- [Encryption](#encryption-2) -- [Decryption](#decryption) -- [Signing](#signing-2) - [Verifying signature](#verifying-signature) - [SSH](#ssh) * [Create configuration](#create-configuration) @@ -64,70 +60,133 @@ If you have a comment or suggestion, please open an [issue](https://github.com/d All YubiKeys except the blue "security key" model are compatible with this guide. NEO models are limited to 2048-bit RSA keys. See [Compare YubiKeys](https://www.yubico.com/products/yubikey-hardware/compare-yubikeys/). -Consider purchasing a pair of YubiKeys, programming both, and storing one in a safe secondary location, in case of loss or damage to the first key. +You will also need several small storage devices for booting a live image, creating backups of private and public keys. # Verify YubiKey -To confirm your YubiKey is genuine open a [browser with U2F support](https://support.yubico.com/support/solutions/articles/15000009591-how-to-confirm-your-yubico-device-is-genuine-with-u2f) and go to [https://www.yubico.com/genuine/](https://www.yubico.com/genuine/). Insert your Yubico device, and click `Verify Device` to begin the process. Touch the YubiKey when prompted, and if asked, allow it to see the make and model of the device. If you see `Verification complete`, your device is authentic. +To confirm your YubiKey is genuine, open a [browser with U2F support](https://support.yubico.com/support/solutions/articles/15000009591-how-to-confirm-your-yubico-device-is-genuine-with-u2f) to [https://www.yubico.com/genuine/](https://www.yubico.com/genuine/). Insert your Yubico device, and select Verify Device` to begin the process. Touch the YubiKey when prompted, and if asked, allow it to see the make and model of the device. If you see `Verification complete`, your device is authentic. This website verifies the YubiKey's device attestation certificates signed by a set of Yubico CAs, and helps mitigate [supply chain attacks](https://media.defcon.org/DEF%20CON%2025/DEF%20CON%2025%20presentations/DEFCON-25-r00killah-and-securelyfitz-Secure-Tokin-and-Doobiekeys.pdf). # Live image -It is recommended to generate cryptographic keys and configure YubiKey from a secure environment to minimize exposure. One way to do that is by downloading and booting to a [Debian Live](https://www.debian.org/CD/live/) or [Tails](https://tails.boum.org/index.en.html) image loaded from a USB drive into memory. +It is recommended to generate cryptographic keys and configure YubiKey from a secure operating system and ephemeral environment, such as [Debian Live](https://www.debian.org/CD/live/) or [Tails](https://tails.boum.org/index.en.html). -Download the latest image and verify its integrity: +To use Debian, download the latest live image: ```console $ curl -LfO https://cdimage.debian.org/debian-cd/current-live/amd64/iso-hybrid/debian-live-9.9.0-amd64-xfce.iso + $ curl -LfO https://cdimage.debian.org/debian-cd/current-live/amd64/iso-hybrid/SHA512SUMS + $ curl -LfO https://cdimage.debian.org/debian-cd/current-live/amd64/iso-hybrid/SHA512SUMS.sign +``` + +Verify file integrity with GPG: +```console $ gpg --verify SHA512SUMS.sign SHA512SUMS -[...] +gpg: Signature made Sat Apr 27 11:46:08 2019 PDT +gpg: using RSA key DF9B9C49EAA9298432589D76DA87E80D6294BE9B +gpg: Can't check signature: No public key + +$ gpg --recv DF9B9C49EAA9298432589D76DA87E80D6294BE9B +gpg: key 0xDA87E80D6294BE9B: 61 signatures not checked due to missing keys +gpg: key 0xDA87E80D6294BE9B: public key "Debian CD signing key " imported +gpg: marginals needed: 3 completes needed: 1 trust model: pgp +gpg: depth: 0 valid: 1 signed: 0 trust: 0-, 0q, 0n, 0m, 0f, 1u +gpg: Total number processed: 1 +gpg: imported: 1 + +$ gpg --verify SHA512SUMS.sign SHA512SUMS +gpg: Signature made Sat Apr 27 11:46:08 2019 PDT +gpg: using RSA key DF9B9C49EAA9298432589D76DA87E80D6294BE9B gpg: Good signature from "Debian CD signing key " [unknown] -[...] +gpg: WARNING: This key is not certified with a trusted signature! +gpg: There is no indication that the signature belongs to the owner. +Primary key fingerprint: DF9B 9C49 EAA9 2984 3258 9D76 DA87 E80D 6294 BE9B $ grep $(sha512sum debian-live-9.9.0-amd64-xfce.iso) SHA512SUMS SHA512SUMS:ae064cc399126214e4aa165fdbf9659047dd2af2d3b0ca57dd5f2686d1d3730019cfe3c56ac48db2af56eb856dbca75e642fadf56bc04c538b44d3d3a2982283 debian-live-9.9.0-amd64-xfce.iso ``` -Mount a USB disk and copy the image over to it: +If the key cannot be received, try changing your DNS resolver and/or specific keyserver: + +```console +$ gpg --keyserver hkps://keyserver.ubuntu.com:443 --recv DF9B9C49EAA9298432589D76DA87E80D6294BE9B +``` + +Mount a storage device and copy the image to it: + +**Linux** + +```console +$ sudo dmesg | tail +usb-storage 3-2:1.0: USB Mass Storage device detected +scsi host2: usb-storage 3-2:1.0 +scsi 2:0:0:0: Direct-Access TS-RDF5 SD Transcend TS3A PQ: 0 ANSI: 6 +sd 2:0:0:0: Attached scsi generic sg1 type 0 +sd 2:0:0:0: [sdb] 31116288 512-byte logical blocks: (15.9 GB/14.8 GiB) +sd 2:0:0:0: [sdb] Write Protect is off +sd 2:0:0:0: [sdb] Mode Sense: 23 00 00 00 +sd 2:0:0:0: [sdb] Write cache: disabled, read cache: enabled, doesn't support DPO or FUA +sdb: sdb1 sdb2 +sd 2:0:0:0: [sdb] Attached SCSI removable disk + +$ sudo dd if=debian-live-9.9.0-amd64-xfce.iso of=/dev/sdb bs=4M +465+1 records in +465+1 records out +1951432704 bytes (2.0 GB, 1.8 GiB) copied, 42.8543 s, 45.5 MB/s +``` + +**OpenBSD** ```console -$ sudo dd if=debian-live-9.9.0-amd64-xfce.iso of=/dev/sdc bs=4M && sync +$ dmesg | tail -n2 +sd2 at scsibus4 targ 1 lun 0: SCSI4 0/direct removable serial.0000000000000 +sd2: 15193MB, 512 bytes/sector, 31116288 sectors + +$ doas dd if=debian-live-9.9.0-amd64-xfce.iso of=/dev/rsd2c bs=4m +465+1 records in +465+1 records out +1951432704 bytes transferred in 139.125 secs (14026448 bytes/sec) ``` Shut down the computer and disconnect any hard drives and unnecessary peripheral devices. -Plug in the USB disk and boot to the live image. Configure networking to continue. If the screen locks, unlock with user/live. +Consider using secure hardware like a ThinkPad X230 running [Coreboot](https://www.coreboot.org/) and cleaned of [Intel ME](https://github.com/corna/me_cleaner). # Required software -Install several packages required for the following steps: +Boot the live image and configure networking. + +**Note** If the screen locks, unlock with credentials: user/live. + +Open the terminal and install several required packages: **Debian/Ubuntu** ```console $ sudo apt-get update && sudo apt-get install -y \ - curl gnupg2 gnupg-agent \ - cryptsetup scdaemon pcscd \ - yubikey-personalization \ - dirmngr \ - secure-delete \ - hopenpgp-tools + curl gnupg2 gnupg-agent dirmngr \ + cryptsetup scdaemon pcscd \ + yubikey-personalization \ + secure-delete hopenpgp-tools ``` -**Arch Linux** +**Arch** ```console -$ sudo pacman -Syu gnupg2 pcsclite ccid yubikey-personalization hopenpgp-tools +$ sudo pacman -Syu \ + gnupg2 pcsclite ccid \ + yubikey-personalization hopenpgp-tools ``` **RHEL7** ```console -$ sudo yum install -y gnupg2 pinentry-curses pcsc-lite pcsc-lite-libs gnupg2-smime +$ sudo yum install -y \ + gnupg2 pinentry-curses pcsc-lite pcsc-lite-libs gnupg2-smime ``` **OpenBSD** @@ -148,55 +207,60 @@ $ brew install gnupg yubikey-personalization hopenpgp-tools ykman pinentry-mac Download and install [Gpg4Win](https://www.gpg4win.org/) and [PuTTY](https://putty.org). -**Note** You may also need more recent versions of [yubikey-personalization](https://developers.yubico.com/yubikey-personalization/Releases/) and [yubico-c](https://developers.yubico.com/yubico-c/Releases/). +You may also need more recent versions of [yubikey-personalization](https://developers.yubico.com/yubikey-personalization/Releases/) and [yubico-c](https://developers.yubico.com/yubico-c/Releases/). ## Entropy -Generating keys will require a lot of randomness. To check the available bits of entropy available on Linux: +Generating cryptographic keys requires high-quality [randomness](https://www.random.org/randomness/), measured as entropy. + +To check the available entropy available on Linux: ```console $ cat /proc/sys/kernel/random/entropy_avail 849 ``` -**Optional** A hardware random number generator like [OneRNG](http://onerng.info/onerng/) will increase the speed of entropy generation and possibly its quality. To install and configure OneRNG: +Most operating systems use software-based pseudorandom number generators. A hardware random number generator like [OneRNG](http://onerng.info/onerng/) will [increase the speed](https://lwn.net/Articles/648550/) of entropy generation and possibly the quality. + +Plug in the device, then install and configure OneRNG software: ```console -$ sudo apt-get install -y rng-tools at python-gnupg openssl +$ sudo apt-get install -y \ + at rng-tools python-gnupg openssl $ curl -LfO https://github.com/OneRNG/onerng.github.io/raw/master/sw/onerng_3.6-1_all.deb $ sha256sum onerng_3.6-1_all.deb -a9ccf7b04ee317dbfc91518542301e2d60ebe205d38e80563f29aac7cd845ccb +a9ccf7b04ee317dbfc91518542301e2d60ebe205d38e80563f29aac7cd845ccb onerng_3.6-1_all.deb $ sudo dpkg -i onerng_3.6-1_all.deb $ echo "HRNGDEVICE=/dev/ttyACM0" | sudo tee /etc/default/rng-tools +$ sudo atd + $ sudo service rng-tools restart ``` -If the service fails to start, kick off `atd` and try again: +Test by emptying `/dev/random` - the light on the device should dim briefly: ```console -$ sudo atd ; sudo service rng-tools restart +$ cat /dev/random >/dev/null +[Press Control-C] ``` -Plug in the OneRNG and empty `/dev/random` - the light on the device should dim briefly. Verify the available entropy pool is re-seeded. +Verify the available entropy pool is re-seeded: ```console -$ cat /dev/random >/dev/null -[Control-C] - $ cat /proc/sys/kernel/random/entropy_avail 3049 ``` -An entropy pool value greater than 3000 is sufficient. +An entropy pool value greater than 2000 is sufficient. # Creating keys -Create a temporary directory which will be deleted on [reboot](https://en.wikipedia.org/wiki/Tmpfs): +Create a temporary directory which will be cleared on [reboot](https://en.wikipedia.org/wiki/Tmpfs): ```console $ export GNUPGHOME=$(mktemp -d) ; echo $GNUPGHOME @@ -234,7 +298,9 @@ Disable networking for the remainder of the setup. # Master key -The first key to generate is the master key. It will be used for certification only - to issue subkeys that are used for encryption, signing and authentication. This master key should be kept offline at all times and only accessed to revoke or issue new subkeys. +The first key to generate is the master key. It will be used for certification only: to issue subkeys that are used for encryption, signing and authentication. + +**Important** The master key should be kept offline at all times and only accessed to revoke or issue new subkeys. You'll be prompted to enter and verify a passphrase - keep it handy as you'll need it throughout. To generate a strong passphrase which could be written down in a hidden or secure place; or memorized: @@ -243,7 +309,11 @@ $ gpg --gen-random -a 0 24 ydOmByxmDe63u7gqx2XI9eDgpvJwibNH ``` -Generate a new key with GPG, selecting `(8) RSA (set your own capabilities)`, `Certify`-only and `4096` bit keysize. Do not set the key to expire - see [Note #3](#notes). +On Linux, select the password with your mouse to copy it to the clipboard and paste using the middle mouse button or `Shift`-`Insert`. + +Generate a new key with GPG, selecting `(8) RSA (set your own capabilities)`, `Certify` capability only and `4096` bit key size. + +Do not set the master key to expire - see [Note #3](#notes). ```console $ gpg --expert --full-generate-key @@ -302,7 +372,11 @@ 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 +``` +Select a name and email address - neither has to be valid nor existing. + +```console GnuPG needs to construct a user ID to identify your key. Real name: Dr Duh @@ -317,21 +391,18 @@ 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: /tmp.FLZC0xcM/trustdb.gpg: trustdb created gpg: key 0xFF3E7D88647EBCDB marked as ultimately trusted gpg: directory '/tmp.FLZC0xcM/openpgp-revocs.d' created gpg: revocation certificate stored as '/tmp.FLZC0xcM/openpgp-revocs.d/011CE16BD45B27A55BA8776DFF3E7D88647EBCDB.rev' public and secret key created and signed. -Note that this key cannot be used for encryption. You may want to use -the command "--edit-key" to generate a subkey for this purpose. pub rsa4096/0xFF3E7D88647EBCDB 2017-10-09 [C] Key fingerprint = 011C E16B D45B 27A5 5BA8 776D FF3E 7D88 647E BCDB uid Dr Duh ``` -As of GPG [version 2.1](https://www.gnupg.org/faq/whats-new-in-2.1.html#autorev), a revocation certificate is automatically generated at this time. - Export the key ID as a [variable](https://stackoverflow.com/questions/1158091/defining-a-variable-with-or-without-export/1158231#1158231) (`KEYID`) for use later: ```console @@ -340,7 +411,7 @@ $ export KEYID=0xFF3E7D88647EBCDB # Subkeys -Edit the Master key to add subkeys: +Edit the master key to add sub-keys: ```console $ gpg --expert --edit-key $KEYID @@ -353,9 +424,9 @@ sec rsa4096/0xEA5DE91459B80592 [ultimate] (1). Dr Duh ``` -Use 4096-bit keysize - or 2048-bit on NEO. +Use 4096-bit key sizes. -Use a 1 year expiration - it can always be renewed using the offline Master certification key. +Use a 1 year or shorter expiration - keys can always be renewed using the offline master key. ## Signing @@ -557,9 +628,9 @@ ssb rsa4096/0x5912A795E90DD2CF 2017-10-09 [E] [expires: 2018-10-09] ssb rsa4096/0x3F29127E79649A3D 2017-10-09 [A] [expires: 2018-10-09] ``` -**Optional** Add any additional identities or email addresses now using the `adduid` command. +Add any additional identities or email addresses you wish to associate using the `adduid` command. -To verify with OpenPGP key checks, use the automated [key best practice checker](https://riseup.net/en/security/message-security/openpgp/best-practices#openpgp-key-checks): +**Optional** Verify with OpenPGP key checks, use the automated [key best practice checker](https://riseup.net/en/security/message-security/openpgp/best-practices#openpgp-key-checks): ```console $ gpg --export $KEYID | hokey lint @@ -571,7 +642,7 @@ The output will display any problems with your key in red text. If everything is # Export keys -The Master and subkeys will be encrypted with your passphrase when exported. +The master key and sub-keys will be encrypted with your passphrase when exported. Save a copy of your keys: @@ -591,41 +662,37 @@ $ gpg --armor --export-secret-subkeys $KEYID -o \path\to\dir\sub.gpg # Backup keys -Once GPG keys are moved to YubiKey, they cannot be extracted again! - -Make sure you have made an **encrypted** backup before proceeding. An encrypted USB drive or container can be made using [VeraCrypt](https://www.veracrypt.fr/en/Downloads.html). - -Also consider using a [paper copy](https://www.jabberwocky.com/software/paperkey/) of the keys as an additional backup measure. +Once GPG keys are moved to YubiKey, they cannot be moved again! Create an **encrypted** backup of the keyring and consider using a [paper copy](https://www.jabberwocky.com/software/paperkey/) of the keys as an additional backup. **Linux** -Attach a USB disk and check its label: +Attach another external storage device and check its label: ```console $ sudo dmesg | tail -scsi8 : usb-storage 2-1:1.0 -usbcore: registered new interface driver usb-storage -scsi 8:0:0:0: USB 0: 0 ANSI: 6 -sd 8:0:0:0: Attached scsi generic sg4 type 0 -sd 8:0:0:0: [sde] 62980096 512-byte logical blocks: (32.2 GB/30.0 GiB) -sd 8:0:0:0: [sde] Write Protect is off -sd 8:0:0:0: [sde] Mode Sense: 43 00 00 00 -sd 8:0:0:0: [sde] Attached SCSI removable disk +usb-storage 4-2:1.0: USB Mass Storage device detected +scsi host7: usb-storage 4-2:1.0 +scsi 7:0:0:0: Direct-Access TS-RDF5 SD Transcend TS37 PQ: 0 ANSI: 6 +sd 7:0:0:0: Attached scsi generic sg1 type 0 +sd 7:0:0:0: [sdb] 31116288 512-byte logical blocks: (15.9 GB/14.8 GiB) +sd 7:0:0:0: [sdb] Write Protect is off +sd 7:0:0:0: [sdb] Mode Sense: 23 00 00 00 +sd 7:0:0:0: [sdb] Write cache: disabled, read cache: enabled, doesn't support DPO or FUA +sdb: sdb1 +sd 7:0:0:0: [sdb] Attached SCSI removable disk ``` -Check the size to make sure it's the right device: +Write it with random data to prepare for encryption: ```console -$ sudo fdisk -l /dev/sde -Disk /dev/sde: 30 GiB, 32245809152 bytes, 62980096 sectors -/dev/sde1 2048 62980095 62978048 30G 6 FAT16 +$ sudo dd if=/dev/urandom of=/dev/sdb bs=4M ``` Erase and create a new partition table: ```console -$ sudo fdisk /dev/sde -Welcome to fdisk (util-linux 2.25.2). +$ sudo fdisk /dev/sdb +Welcome to fdisk (util-linux 2.29.2). Command (m for help): o Created a new DOS disklabel with disk identifier 0xeac7ee35. @@ -636,22 +703,22 @@ Calling ioctl() to re-read partition table. Syncing disks. ``` -Remove and reinsert the USB drive, then create a new partition, selecting defaults: +Create a new partition with a 10 Megabyte size: ```console -$ sudo fdisk /dev/sde -Welcome to fdisk (util-linux 2.25.2). +$ sudo fdisk /dev/sdb +Welcome to fdisk (util-linux 2.29.2). Command (m for help): n Partition type p primary (0 primary, 0 extended, 4 free) e extended (container for logical partitions) -Select (default p): p -Partition number (1-4, default 1): 1 +Select (default p): +Partition number (1-4, default 1): First sector (2048-62980095, default 2048): -Last sector, +sectors or +size{K,M,G,T,P} (2048-62980095, default 62980095): +Last sector, +sectors or +size{K,M,G,T,P} (2048-62980095, default 62980095): +10M -Created a new partition 1 of type 'Linux' and of size 30 GiB. +Created a new partition 1 of type 'Linux' and of size 10 MiB. Command (m for help): w The partition table has been altered. @@ -662,11 +729,11 @@ Syncing disks. Use [LUKS](https://askubuntu.com/questions/97196/how-secure-is-an-encrypted-luks-filesystem) to encrypt the new partition: ```console -$ sudo cryptsetup luksFormat /dev/sde1 +$ sudo cryptsetup luksFormat /dev/sdb1 WARNING! ======== -This will overwrite data on /dev/sde1 irrevocably. +This will overwrite data on /dev/sdb1 irrevocably. Are you sure? (Type uppercase yes): YES Enter passphrase: @@ -676,27 +743,24 @@ Verify passphrase: Mount the partition: ```console -$ sudo cryptsetup luksOpen /dev/sde1 usb -Enter passphrase for /dev/sde1: +$ sudo cryptsetup luksOpen /dev/sdb1 usb +Enter passphrase for /dev/sdb1: ``` Create a filesystem: ```console -$ sudo mkfs.ext4 /dev/mapper/usb -L usb -mke2fs 1.43.4 (31-Jan-2017) -Creating filesystem with 7871744 4k blocks and 1970416 inodes +$ sudo mkfs.ext2 /dev/mapper/usb -L usb +Creating filesystem with 10240 1k blocks and 2560 inodes Superblock backups stored on blocks: - 32768, 98304, 163840, 229376, 294912, 819200, 884736, 1605632, 2654208, - 4096000 + 8193 Allocating group tables: done Writing inode tables: done -Creating journal (32768 blocks): done Writing superblocks and filesystem accounting information: done ``` -Mount the filesystem and copy the temporary GNUPG directory: +Mount the filesystem and copy the temporary directory with the keyring: ```console $ sudo mkdir /mnt/encrypted-usb @@ -708,14 +772,75 @@ $ sudo cp -avi $GNUPGHOME /mnt/encrypted-usb Keep the backup mounted if you plan on setting up two or more keys as `keytocard` **will [delete](https://lists.gnupg.org/pipermail/gnupg-users/2016-July/056353.html) the local copy** on save. -Otherwise, unmount and disconnected the encrypted USB disk: +Otherwise, unmount and disconnected the encrypted volume: ```console -$ sudo umount /mnt +$ sudo umount /mnt/encrypted-usb $ sudo cryptsetup luksClose usb ``` +Create another partition to store the public key, or skip this step if you plan on uploading it to a key server. + +**Important** Without the *public* key, you will not be able to use GPG to encrypt, decrypt, nor sign messages. However, you will still be able to use YubiKey for SSH authentication. + +```console +$ sudo fdisk /dev/sdb + +Command (m for help): n +Partition type + p primary (1 primary, 0 extended, 3 free) + e extended (container for logical partitions) +Select (default p): +Partition number (2-4, default 2): +First sector (22528-31116287, default 22528): +Last sector, +sectors or +size{K,M,G,T,P} (22528-31116287, default 31116287): +10M + +Created a new partition 2 of type 'Linux' and of size 10 MiB. + +Command (m for help): w +The partition table has been altered. +Calling ioctl() to re-read partition table. +Syncing disks. + +$ sudo mkfs.ext2 /dev/sdb2 +Creating filesystem with 10240 1k blocks and 2560 inodes +Superblock backups stored on blocks: + 8193 + +Allocating group tables: done +Writing inode tables: done +Writing superblocks and filesystem accounting information: done + +$ sudo mkdir /mnt/public + +$ sudo mount /dev/sdb2 /mnt/public/ + +$ gpg --armor --export $KEYID | sudo tee /mnt/public/$KEYID.txt +-----BEGIN PGP PUBLIC KEY BLOCK----- +[...] +``` + +**Windows** + +```console +$ gpg --armor --export $KEYID -o \path\to\dir\pubkey.gpg +``` + +**Optional** Upload the public key to a [public keyserver](https://debian-administration.org/article/451/Submitting_your_GPG_key_to_a_keyserver): + +```console +$ gpg --send-key $KEYID + +$ gpg --keyserver pgp.mit.edu --send-key $KEYID + +$ gpg --keyserver keys.gnupg.net --send-key $KEYID + +$ gpg --keyserver hkps://keyserver.ubuntu.com:443 --send-key $KEYID +``` + +After some time, the public key will to propagate to [other](https://pgp.key-server.io/pks/lookup?search=doc%40duh.to&fingerprint=on&op=vindex) [servers](https://pgp.mit.edu/pks/lookup?search=doc%40duh.to&op=index). + **OpenBSD** Attach a USB disk and determine its label: @@ -753,7 +878,7 @@ Re-type passphrase: softraid0: CRYPTO volume attached as sd3 ``` -Make an `i` partition, then make and mount the filesystem: +Create an `i` partition, then create and mount the filesystem: ```console $ doas fdisk -iy sd3 @@ -846,7 +971,7 @@ General key info..: [none] ## Change PIN -The default PIN is `123456` and default Admin PIN (PUK) is `12345678`. CCID-mode PINs can be up to 127 ASCII characters long. +The default PIN is `123456` and default Admin PIN (PUK) is `12345678`. CCID-mode PINs can be up to 127 ASCII characters. The Admin PIN is required for some card operations and to unblock a PIN that has been entered incorrectly more than three times. See the GnuPG documentation on [Managing PINs](https://www.gnupg.org/howtos/card-howto/en/ch03s02.html) for details. @@ -899,7 +1024,7 @@ Language preferences: en gpg/card> login Login data (account name): doc@duh.to -gpg/card> [Press Enter] +gpg/card> list Application ID ...: D2760001240102010006055532110000 Version ..........: 2.1 @@ -1034,7 +1159,7 @@ gpg> save # Verify card -Verify the subkeys have moved to YubiKey as indicated by `ssb>`: +Verify the sub-keys have been moved to YubiKey as indicated by `ssb>`: ```console $ gpg --list-secret-keys @@ -1048,42 +1173,14 @@ ssb> rsa4096/0x5912A795E90DD2CF 2017-10-09 [E] [expires: 2018-10-09] ssb> rsa4096/0x3F29127E79649A3D 2017-10-09 [A] [expires: 2018-10-09] ``` -# Export public key - -Mount another USB disk to copy the *public* key, or save it somewhere where it can be easily accessed later. - -**Important** Without importing the *public* key, you will not be able to use GPG to encrypt, decrypt, nor sign messages. However, you will still be able to use YubiKey for SSH authentication. - -```console -$ gpg --armor --export $KEYID > /mnt/public-usb-key/pubkey.txt -``` - -Windows: - -```console -$ gpg --armor --export $KEYID -o \path\to\dir\pubkey.gpg -``` - -**Optional** Upload the public key to a [public keyserver](https://debian-administration.org/article/451/Submitting_your_GPG_key_to_a_keyserver): - -```console -$ gpg --send-key $KEYID - -$ gpg --keyserver pgp.mit.edu --send-key $KEYID - -$ gpg --keyserver keys.gnupg.net --send-key $KEYID -``` - -After some time, the public key will to propagate to [other](https://pgp.key-server.io/pks/lookup?search=doc%40duh.to&fingerprint=on&op=vindex) [servers](https://pgp.mit.edu/pks/lookup?search=doc%40duh.to&op=index). - # Cleanup Ensure you have: -* Saved the Encryption, Signing and Authentication subkeys to YubiKey. +* Saved the encryption, signing and authentication sub-keys to YubiKey. * Saved the YubiKey PINs which you changed from defaults. -* Saved the password to the Master key. -* Saved a copy of the Master key, subkeys and revocation certificates on an encrypted volume stored offline. +* Saved the password to the master key. +* Saved a copy of the master key, sub-keys and revocation certificates on an encrypted volume, to be stored offline. * Saved the password to that encrypted volume in a separate location. * Saved a copy of the public key somewhere easily accessible later. @@ -1105,27 +1202,23 @@ Install required programs: ```console $ sudo apt-get update && sudo apt-get install -y \ - curl gnupg2 gnupg-agent \ - cryptsetup scdaemon pcscd + gnupg2 gnupg-agent scdaemon pcscd ``` Download [drduh/config/gpg.conf](https://github.com/drduh/config/blob/master/gpg.conf): ```console -$ mkdir ~/.gnupg ; curl -o ~/.gnupg/gpg.conf https://raw.githubusercontent.com/drduh/config/master/gpg.conf +$ cd ~/.gnupg ; wget https://raw.githubusercontent.com/drduh/config/master/gpg.conf -$ chmod 600 ~/.gnupg/gpg.conf +$ chmod 600 gpg.conf ``` # Import public key -To import the public key from a file on an encrypted USB disk: +To import the public key from the non-encrypted volume created earlier: ```console -$ sudo cryptsetup luksOpen /dev/sdd1 usb -Enter passphrase for /dev/sdd1: - -$ sudo mount /dev/mapper/usb /mnt +$ sudo mount /dev/sdb2 /mnt $ gpg --import /mnt/pubkey.txt gpg: key 0xFF3E7D88647EBCDB: public key "Dr Duh " imported @@ -1152,12 +1245,12 @@ $ sudo apt-get install -y gnupg-curl ## Trust master key -Edit the Master key to assign it ultimate trust by selecting `trust` then option `5`: +Edit the master key to assign it ultimate trust by selecting `trust` then option `5`: ```console -$ gpg --edit-key $KEYID +$ export KEYID=0xFF3E7D88647EBCDB -Secret key is available. +$ gpg --edit-key $KEYID gpg> trust pub 4096R/0xFF3E7D88647EBCDB created: 2016-05-24 expires: never usage: C @@ -1187,12 +1280,12 @@ sub 4096R/0x5912A795E90DD2CF created: 2017-10-09 expires: 2018-10-09 usage: sub 4096R/0x3F29127E79649A3D created: 2017-10-09 expires: 2018-10-09 usage: A [ unknown] (1). Dr Duh -gpg> save +gpg> quit ``` # Insert YubiKey -Re-connect YubiKey and check the status: +Remove and re-insert the YubiKey and check the status: ```console $ gpg --card-status @@ -1230,122 +1323,38 @@ ssb> 4096R/0x3F29127E79649A3D created: 2017-10-09 expires: 2018-10-09 **Note** If you see `General key info..: [none]` in the output instead - go back and import the public key using the previous step. -# Encryption +Encrypt a message to your own key (useful for storing passwords and other credentials): ```console -$ echo "test message string" | gpg --encrypt --armor --recipient $KEYID ------BEGIN PGP MESSAGE----- - -hQIMA1kSp5XpDdLPAQ/+JyYfLaUS/+llEzQaKDb5mWhG4HlUgD99dNJUXakm085h -PSSt3I8Ac0ctwyMnenZvBEbHMqdRnfZJsj5pHidKcAZrhgs+he+B1tdZ/KPa8inx -NIGqd8W1OraVSFmPEdC1kQ5he6R/WCDH1NNel9+fvLtQDCBQaFae/s3yXCSSQU6q -HKCJLyHK8K9hDvgFmXOY8j1qTknBvDbmYdcCKVE1ejgpUCi3WatusobpWozsp0+b -6DN8bXyfxLPYm1PTLfW7v4kwddktB8eVioV8A45lndJZvliSqDwxhrwyE5VGsArS -NmqzBkCaOHQFr0ofL91xgwpCI5kM2ukIR5SxUO4hvzlHn58QVL9GfAyCHMFtJs3o -Q9eiR0joo9TjTwR8XomVhRJShrrcPeGgu3YmIak4u7OndyBFpu2E79RQ0ehpl2gY -tSECB6mNd/gt0Wy3y15ccaFI4CVP6jrMN6q3YhXqNC7GgI/OWkVZIAgUFYnbmIQe -tQ3z3wlbvFFngeFy5IlhsPduK8T9XgPnOtgQxHaepKz0h3m2lJegmp4YZ4CbS9h6 -kcBTUjys5Vin1SLuqL4PhErzmlAZgVzG2PANsnHYPe2hwN4NlFtOND1wgBCtBFBs -1pqz1I0O+jmyId+jVlAK076c2AwdkVbokKUcIT/OcTc0nwHjOUttJGmkUHlbt/nS -iAFNniSfzf6fwAFHgsvWiRJMa3keolPiqoUdh0tBIiI1zxOMaiTL7C9BFdpnvzYw -Krj0pDc7AlF4spWhm58WgAW20P8PGcVQcN6mSTG8jKbXVSP3bvgPXkpGAOLKMV/i -pLORcRPbauusBqovgaBWU/i3pMYrbhZ+LQbVEaJlvblWu6xe8HhS/jo= -=pzkv ------END PGP MESSAGE----- +$ echo "test message string" | gpg --encrypt --armor --recipient $KEYID -o encrypted.txt ``` To encrypt to multiple recipients (or to multiple keys): ```console -$ echo "test message string" | gpg --encrypt --armor --recipient $KEYID_0 --recipient $KEYID_1 --recipient $KEYID_2 ------BEGIN PGP MESSAGE----- -[...] +$ echo "test message string" | gpg --encrypt --armor --recipient $KEYID_0 --recipient $KEYID_1 --recipient $KEYID_2 -o encrypted.txt ``` -# Decryption +Decrypt the message: ```console -$ gpg --decrypt --armor ------BEGIN PGP MESSAGE----- - -hQIMA1kSp5XpDdLPAQ/+JyYfLaUS/+llEzQaKDb5mWhG4HlUgD99dNJUXakm085h -PSSt3I8Ac0ctwyMnenZvBEbHMqdRnfZJsj5pHidKcAZrhgs+he+B1tdZ/KPa8inx -NIGqd8W1OraVSFmPEdC1kQ5he6R/WCDH1NNel9+fvLtQDCBQaFae/s3yXCSSQU6q -HKCJLyHK8K9hDvgFmXOY8j1qTknBvDbmYdcCKVE1ejgpUCi3WatusobpWozsp0+b -6DN8bXyfxLPYm1PTLfW7v4kwddktB8eVioV8A45lndJZvliSqDwxhrwyE5VGsArS -NmqzBkCaOHQFr0ofL91xgwpCI5kM2ukIR5SxUO4hvzlHn58QVL9GfAyCHMFtJs3o -Q9eiR0joo9TjTwR8XomVhRJShrrcPeGgu3YmIak4u7OndyBFpu2E79RQ0ehpl2gY -tSECB6mNd/gt0Wy3y15ccaFI4CVP6jrMN6q3YhXqNC7GgI/OWkVZIAgUFYnbmIQe -tQ3z3wlbvFFngeFy5IlhsPduK8T9XgPnOtgQxHaepKz0h3m2lJegmp4YZ4CbS9h6 -kcBTUjys5Vin1SLuqL4PhErzmlAZgVzG2PANsnHYPe2hwN4NlFtOND1wgBCtBFBs -1pqz1I0O+jmyId+jVlAK076c2AwdkVbokKUcIT/OcTc0nwHjOUttJGmkUHlbt/nS -iAFNniSfzf6fwAFHgsvWiRJMa3keolPiqoUdh0tBIiI1zxOMaiTL7C9BFdpnvzYw -Krj0pDc7AlF4spWhm58WgAW20P8PGcVQcN6mSTG8jKbXVSP3bvgPXkpGAOLKMV/i -pLORcRPbauusBqovgaBWU/i3pMYrbhZ+LQbVEaJlvblWu6xe8HhS/jo= -=pzkv ------END PGP MESSAGE----- -gpg: encrypted with 4096-bit RSA key, ID 0x5912A795E90DD2CF, created -2016-05-24 - "Dr Duh " - -[Press Control-D] - +$ gpg --decrypt --armor cipher.txt +gpg: anonymous recipient; trying secret key 0x0000000000000000 ... +gpg: okay, we are the anonymous recipient. +gpg: encrypted with RSA key, ID 0x0000000000000000 test message string ``` -# Signing +Sign a message: ```console -$ echo "test message string" | gpg --armor --clearsign --default-key 0xBECFA3C1AE191D15 ------BEGIN PGP SIGNED MESSAGE----- -Hash: SHA512 - -test message string ------BEGIN PGP SIGNATURE----- - -iQIcBAEBCgAGBQJXRPo8AAoJEL7Po8GuGR0Vh8wP/jYXTR8SAZIZSMVCOyAjH37f -k6JxB0rF928WDYPihjo/d0Jd+XpoV1g+oipDRjP78xqR9H/CJZlE10IPQbNaomFs -+3RGxA3Zr085cVFoixI8rxYOSu0Vs2cAzAbJHNcOcD7vXxTHcX4T8kfKoF9A4U1u -XTJ42eEjpO0fX76tFX2/Uzxl43ES0dO7Y82ho7xcnaYwakVUEcWfUpfDAroLKZOs -wCZGr8Z64QDQzxQ9L45Zc61wMx9JEIWD4BnagllfeOYrEwTJfYG8uhDDNYx0jjJp -j1PBHn5d556aX6DHUH05kq3wszvQ4W40RctLgAA3l1VnEKebhBKjLZA/EePAvQV4 -QM7MFUV1X/pi2zlyoZSnHkVl8b5Q7RU5ZtRpq9fdkDDepeiUo5PNBUMJER1gn4bm -ri8DtavkwTNWBRLnVR2gHBmVQNN7ZDOkHcfyqR4I9chx6TMpfcxk0zATAHh8Donp -FVPKySifuXpunn+0MwdZl5XkhHGdpdYQz4/LAZUGhrA9JTnFtc4cl4JrTzufF8Sr -c3JJumMsyGvw9OQKQHF8gHme4PBu/4P31LpfX9wzPOTpJaI31Sg5kdJLTo9M9Ppo -uvkmJS7ETjLQZOsRyAEn7gcEKZQGPQcNAgfEgQPoepS/KvvI68u+JMJm4n24k2kQ -fEkp501u8kAZkWauhiL+ -=+ylJ ------END PGP SIGNATURE----- +$ echo "test message string" | gpg --armor --clearsign > signed.txt ``` -# Verifying signature +Verify the signature: ```console -$ gpg -gpg: Go ahead and type your message ... ------BEGIN PGP SIGNED MESSAGE----- -Hash: SHA512 - -test message string ------BEGIN PGP SIGNATURE----- - -iQIcBAEBCgAGBQJXRPo8AAoJEL7Po8GuGR0Vh8wP/jYXTR8SAZIZSMVCOyAjH37f -+3RGxA3Zr085cVFoixI8rxYOSu0Vs2cAzAbJHNcOcD7vXxTHcX4T8kfKoF9A4U1u -XTJ42eEjpO0fX76tFX2/Uzxl43ES0dO7Y82ho7xcnaYwakVUEcWfUpfDAroLKZOs -wCZGr8Z64QDQzxQ9L45Zc61wMx9JEIWD4BnagllfeOYrEwTJfYG8uhDDNYx0jjJp -j1PBHn5d556aX6DHUH05kq3wszvQ4W40RctLgAA3l1VnEKebhBKjLZA/EePAvQV4 -QM7MFUV1X/pi2zlyoZSnHkVl8b5Q7RU5ZtRpq9fdkDDepeiUo5PNBUMJER1gn4bm -ri8DtavkwTNWBRLnVR2gHBmVQNN7ZDOkHcfyqR4I9chx6TMpfcxk0zATAHh8Donp -FVPKySifuXpunn+0MwdZl5XkhHGdpdYQz4/LAZUGhrA9JTnFtc4cl4JrTzufF8Sr -c3JJumMsyGvw9OQKQHF8gHme4PBu/4P31LpfX9wzPOTpJaI31Sg5kdJLTo9M9Ppo -uvkmJS7ETjLQZOsRyAEn7gcEKZQGPQcNAgfEgQPoepS/KvvI68u+JMJm4n24k2kQ -fEkp501u8kAZkWauhiL+ -=+ylJ ------END PGP SIGNATURE----- - -[Press Control-D] - +$ gpg --verify signed.txt gpg: Signature made Wed 25 May 2016 00:00:00 AM UTC gpg: using RSA key 0xBECFA3C1AE191D15 gpg: Good signature from "Dr Duh " [ultimate] @@ -1718,7 +1727,7 @@ And reload the SSH daemon (e.g., `sudo service sshd reload`). # Notes 1. YubiKey has two configurations: one invoked with a short press, and the other with a long press. By default, the short-press mode is configured for HID OTP - a brief touch will emit an OTP string starting with `cccccccc`. If you rarely use the OTP mode, you can swap it to the second configuration via the YubiKey Personalization tool. If you *never* use OTP, you can disable it entirely using the [YubiKey Manager](https://developers.yubico.com/yubikey-manager) application (note, this not the similarly named YubiKey NEO Manager). -1. Programming YubiKey for GPG keys still lets you use its two configurations - [OTP](https://www.yubico.com/faq/what-is-a-one-time-password-otp/) and [static password](https://www.yubico.com/products/services-software/personalization-tools/static-password/) modes, for example. +1. Programming YubiKey for GPG keys still lets you use its other configurations - [U2F](https://en.wikipedia.org/wiki/Universal_2nd_Factor), [OTP](https://www.yubico.com/faq/what-is-a-one-time-password-otp/) and [static password](https://www.yubico.com/products/services-software/personalization-tools/static-password/) modes, for example. 1. Setting an expiry essentially forces you to manage your subkeys and announces to the rest of the world that you are doing so. Setting an expiry on a primary key is ineffective for protecting the key from loss - whoever has the primary key can simply extend its expiry period. Revocation certificates are [better suited](https://security.stackexchange.com/questions/14718/does-openpgp-key-expiration-add-to-security/79386#79386) for this purpose. It may be appropriate for your use case to set expiry dates on subkeys. 1. To switch between two or more identities on different keys - unplug the first key and restart gpg-agent, ssh-agent and pinentry with `pkill gpg-agent ; pkill ssh-agent ; pkill pinentry ; eval $(gpg-agent --daemon --enable-ssh-support)`, then plug in the other key and run `gpg-connect-agent updatestartuptty /bye` - then it should be ready for use.