aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/README.md
diff options
context:
space:
mode:
authordrduh <drduh@users.noreply.github.com>2016-01-31 20:58:24 -0500
committerdrduh <drduh@users.noreply.github.com>2016-01-31 20:58:24 -0500
commit172a4292a5b3a29a1121ea4f50d34aa10a3d31cc (patch)
tree55b72bf769d65abbdbe1a3df0ad59a49d26f4938 /README.md
parentInitial commit (diff)
downloadYubiKey-Guide-172a4292a5b3a29a1121ea4f50d34aa10a3d31cc.tar.gz
Create README.md
Diffstat (limited to 'README.md')
-rw-r--r--README.md897
1 files changed, 897 insertions, 0 deletions
diff --git a/README.md b/README.md
new file mode 100644
index 0000000..9714a18
--- /dev/null
+++ b/README.md
@@ -0,0 +1,897 @@
+This is a guide to using YubiKey as a SmartCard for storing GPG keys.
+
+An authentication key can also be created for SSH using gpg-agent.
+
+Keys stored on a smartcard like YubiKey seem more difficult to steal than ones stored on disk, and are convenient for everyday use.
+
+Instructions written on Debian GNU/Linux 8 (jessie) using YubiKey 4 in OTP+CCID mode.
+
+Debian live install images are available from [here](https://www.debian.org/CD/live/) and are suitable for writing to USB keys.
+
+If you have a comment or suggestion, please open an issue on GitHub.
+
+- [Purchase YubiKey](#purchase-yubikey)
+- [Install required software](#install-required-software)
+- [Creating keys](#creating-keys)
+ - [Create temporary working directory for GPG](#create-temporary-working-directory-for-gpg)
+ - [Create configuration](#create-configuration)
+ - [Create master key](#create-master-key)
+ - [Create revocation certificate](#create-revocation-certificate)
+ - [Back up master key](#back-up-master-key)
+ - [Create subkeys](#create-subkeys)
+ - [Signing key](#signing-key)
+ - [Encryption key](#encryption-key)
+ - [Authentication key](#authentication-key)
+ - [Check your work](#check-your-work)
+ - [Export subkeys](#export-subkeys)
+ - [Back up everything](#back-up-everything)
+ - [Configure YubiKey](#configure-yubikey)
+ - [Configure smartcard](#configure-smartcard)
+ - [Change PINs](#change-pins)
+ - [Set optional card information](#set-optional-card-information)
+ - [Transfer keys](#transfer-keys)
+ - [Signature key](#signature-key)
+ - [Encryption key](#encryption-key-1)
+ - [Authentication key](#authentication-key-1)
+ - [Check your work](#check-your-work-1)
+ - [Export public key](#export-public-key)
+- [Using keys](#using-keys)
+ - [Insert YubiKey](#insert-yubikey)
+ - [Import public key](#import-public-key)
+ - [Trust master key](#trust-master-key)
+ - [GnuPG](#gnupg)
+ - [Encryption/decryption](#encryptiondecryption)
+ - [Signing](#signing)
+ - [SSH](#ssh)
+ - [Create configuration](#create-configuration-1)
+ - [Replace ssh-agent with gpg-agent](#replace-ssh-agent-with-gpg-agent)
+ - [Copy public key to server](#copy-public-key-to-server)
+ - [Connect with public key authentication](#connect-with-public-key-authentication)
+- [Notes](#notes)
+- [References](#references)
+
+# Purchase YubiKey
+
+https://www.yubico.com/products/yubikey-hardware/
+
+https://www.yubico.com/store/
+
+https://www.amazon.com/Yubico/b/ref=bl_dp_s_web_10358012011?ie=UTF8&node=10358012011
+
+Consider purchasing a pair and programming both in case of loss or damage.
+
+# Install required software
+
+ $ sudo apt-get install gnupg-agent pinentry-curses scdaemon pcscd yubikey-personalization
+
+# Creating keys
+
+## Create temporary working directory for GPG
+
+ $ export GNUPGHOME=$(mktemp -d) ; echo $GNUPGHOME
+ /tmp/tmp.EBbMfyVDDt
+
+## Create configuration
+
+ $ cat > $GNUPGHOME/gpg.conf
+ use-agent
+ personal-cipher-preferences AES256 AES192 AES CAST5
+ personal-digest-preferences SHA512 SHA384 SHA256 SHA224
+ default-preference-list SHA512 SHA384 SHA256 SHA224 AES256 AES192 AES CAST5 ZLIB BZIP2 ZIP Uncompressed
+ cert-digest-algo SHA512
+ s2k-digest-algo SHA512
+ charset utf-8
+ fixed-list-mode
+ no-comments
+ no-emit-version
+ keyid-format 0xlong
+ list-options show-uid-validity
+ verify-options show-uid-validity
+ with-fingerprint
+ ^D (Press Control-D)
+
+## Create master key
+
+ $ gpg --gen-key
+ gpg (GnuPG) 1.4.18; Copyright (C) 2014 Free Software Foundation, Inc.
+ This is free software: you are free to change and redistribute it.
+ There is NO WARRANTY, to the extent permitted by law.
+
+ Please select what kind of key you want:
+ (1) RSA and RSA (default)
+ (2) DSA and Elgamal
+ (3) DSA (sign only)
+ (4) RSA (sign only)
+ Your selection? 4
+ RSA keys may be between 1024 and 4096 bits long.
+ What keysize do you want? (2048) 4096
+ Requested keysize is 4096 bits
+ Please specify how long the key should be valid.
+ 0 = key does not expire
+ <n> = key expires in n days
+ <n>w = key expires in n weeks
+ <n>m = key expires in n months
+ <n>y = key expires in n years
+ Key is valid for? (0) 0
+ Key does not expire at all
+ Is this correct? (y/N) y
+
+ You need a user ID to identify your key; the software constructs the user ID
+ from the Real Name, Comment and Email Address in this form:
+ "Heinrich Heine (Der Dichter) <heinrichh@duesseldorf.de>"
+
+ Real name: Doctor Duh
+ Email address: drduh@users.noreply.github.com
+ Comment:
+ You selected this USER-ID:
+ "Doctor Duh <drduh@users.noreply.github.com>"
+
+ Change (N)ame, (C)omment, (E)mail or (O)kay/(Q)uit? o
+ You need a Passphrase to protect your secret key.
+
+ 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/tmp.eBbMfyVDDt/trustdb.gpg: trustdb created
+ gpg: key 0x47FE984F98EE7407 marked as ultimately trusted
+ public and secret key created and signed.
+
+ gpg: checking the trustdb
+ gpg: 3 marginal(s) needed, 1 complete(s) needed, PGP trust model
+ gpg: depth: 0 valid: 1 signed: 0 trust: 0-, 0q, 0n, 0m, 0f, 1u
+ pub 4096R/0x47FE984F98EE7407 2016-01-30
+ Key fingerprint = 044C ABD0 9043 F1E0 3785 3979 47FE 984F 98EE 7407
+ uid [ultimate] Doctor Duh <drduh@users.noreply.github.com>
+
+ 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.
+
+## Create revocation certificate
+
+ $ gpg --gen-revoke 0x47FE984F98EE7407 --output $GNUPGHOME/revoke.txt
+
+ sec 4096R/0x47FE984F98EE7407 2016-01-30 Doctor Duh <drduh@users.noreply.github.com>
+
+ Create a revocation certificate for this key? (y/N) y
+ Please select the reason for the revocation:
+ 0 = No reason specified
+ 1 = Key has been compromised
+ 2 = Key is superseded
+ 3 = Key is no longer used
+ Q = Cancel
+ (Probably you want to select 1 here)
+ Your decision? 1
+ Enter an optional description; end it with an empty line:
+ >
+ Reason for revocation: Key has been compromised
+ (No description given)
+ Is this okay? (y/N) y
+
+ You need a passphrase to unlock the secret key for
+ user: "Doctor Duh <drduh@users.noreply.github.com>"
+ 4096-bit RSA key, ID 0x47FE984F98EE7407, created 2016-01-30
+
+ ASCII armored output forced.
+ Revocation certificate created.
+
+ Please move it to a medium which you can hide away; if Mallory gets
+ access to this certificate he can use it to make your key unusable.
+ It is smart to print this certificate and store it away, just in case
+ your media become unreadable. But have some caution: The print system of
+ your machine might store the data and make it available to others!
+
+## Back up master key
+
+ $ gpg --armor --export-secret-keys 0x47FE984F98EE7407 > $GNUPGHOME/master.key
+
+## Create subkeys
+
+ $ gpg --expert --edit-key 0x47FE984F98EE7407
+
+ gpg (GnuPG) 1.4.18; Copyright (C) 2014 Free Software Foundation, Inc.
+ This is free software: you are free to change and redistribute it.
+ There is NO WARRANTY, to the extent permitted by law.
+
+ Secret key is available.
+
+ pub 4096R/0x47FE984F98EE7407 created: 2016-01-30 expires: never usage: SC
+
+ trust: ultimate validity: ultimate
+ [ultimate] (1). Doctor Duh <drduh@users.noreply.github.com>
+
+### Signing key
+
+ gpg> addkey
+ Key is protected.
+
+ You need a passphrase to unlock the secret key for
+ user: "Doctor Duh <drduh@users.noreply.github.com>"
+ 4096-bit RSA key, ID 0x47FE984F98EE7407, created 2016-01-30
+
+ Please select what kind of key you want:
+ (3) DSA (sign only)
+ (4) RSA (sign only)
+ (5) Elgamal (encrypt only)
+ (6) RSA (encrypt only)
+ (7) DSA (set your own capabilities)
+ (8) RSA (set your own capabilities)
+ Your selection? 4
+ RSA keys may be between 1024 and 4096 bits long.
+ What keysize do you want? (2048) 4096
+ Requested keysize is 4096 bits
+ Please specify how long the key should be valid.
+ 0 = key does not expire
+ <n> = key expires in n days
+ <n>w = key expires in n weeks
+ <n>m = key expires in n months
+ <n>y = key expires in n years
+ Key is valid for? (0) 0
+ Key does not expire at all
+ Is this correct? (y/N) y
+ Really create? (y/N) y
+ We need to generate a lot of random bytes. It is a good idea to perform
+ some other action (type on the keyboard, move the mouse, utilize the
+ disks) during the prime generation; this gives the random number
+ generator a better chance to gain enough entropy.
+ .....+++++
+ .+++++
+
+ pub 4096R/0x47FE984F98EE7407 created: 2016-01-30 expires: never usage: SC
+
+ trust: ultimate validity: ultimate
+ sub 4096R/0xE8E7855AA5AE79A7 created: 2016-01-30 expires: never usage: S
+
+ [ultimate] (1). Doctor Duh <drduh@users.noreply.github.com>
+
+### Encryption key
+
+ gpg> addkey
+ Key is protected.
+
+ You need a passphrase to unlock the secret key for
+ user: "Doctor Duh <drduh@users.noreply.github.com>"
+ 4096-bit RSA key, ID 0x47FE984F98EE7407, created 2016-01-30
+
+ Please select what kind of key you want:
+ (3) DSA (sign only)
+ (4) RSA (sign only)
+ (5) Elgamal (encrypt only)
+ (6) RSA (encrypt only)
+ (7) DSA (set your own capabilities)
+ (8) RSA (set your own capabilities)
+ Your selection? 6
+ RSA keys may be between 1024 and 4096 bits long.
+ What keysize do you want? (2048) 4096
+ Requested keysize is 4096 bits
+ Please specify how long the key should be valid.
+ 0 = key does not expire
+ <n> = key expires in n days
+ <n>w = key expires in n weeks
+ <n>m = key expires in n months
+ <n>y = key expires in n years
+ Key is valid for? (0) 0
+ Key does not expire at all
+ Is this correct? (y/N) y
+ Really create? (y/N) y
+ We need to generate a lot of random bytes. It is a good idea to perform
+ some other action (type on the keyboard, move the mouse, utilize the
+ disks) during the prime generation; this gives the random number
+ generator a better chance to gain enough entropy.
+
+ .+++++
+ ...........+++++
+
+ pub 4096R/0x47FE984F98EE7407 created: 2016-01-30 expires: never usage: SC
+
+ trust: ultimate validity: ultimate
+ sub 4096R/0xE8E7855AA5AE79A7 created: 2016-01-30 expires: never usage: S
+
+ sub 4096R/0x39988E0390CB4B0C created: 2016-01-30 expires: never usage: E
+
+ [ultimate] (1). Doctor Duh <drduh@users.noreply.github.com>
+
+### Authentication key
+
+ gpg> addkey
+ Key is protected.
+
+ You need a passphrase to unlock the secret key for
+ user: "Doctor Duh <drduh@users.noreply.github.com>"
+ 4096-bit RSA key, ID 0x47FE984F98EE7407, created 2016-01-30
+
+ Please select what kind of key you want:
+ (3) DSA (sign only)
+ (4) RSA (sign only)
+ (5) Elgamal (encrypt only)
+ (6) RSA (encrypt only)
+ (7) DSA (set your own capabilities)
+ (8) RSA (set your own capabilities)
+ Your selection? 8
+
+ Possible actions for a RSA key: Sign Encrypt Authenticate
+ Current allowed actions: Sign Encrypt
+
+ (S) Toggle the sign capability
+ (E) Toggle the encrypt capability
+ (A) Toggle the authenticate capability
+ (Q) Finished
+
+ Your selection? s
+
+ Possible actions for a RSA key: Sign Encrypt Authenticate
+ Current allowed actions: Encrypt
+
+ (S) Toggle the sign capability
+ (E) Toggle the encrypt capability
+ (A) Toggle the authenticate capability
+ (Q) Finished
+
+ Your selection? e
+
+ Possible actions for a RSA key: Sign Encrypt Authenticate
+ Current allowed actions:
+
+ (S) Toggle the sign capability
+ (E) Toggle the encrypt capability
+ (A) Toggle the authenticate capability
+ (Q) Finished
+
+ Your selection? a
+
+ Possible actions for a RSA key: Sign Encrypt Authenticate
+ Current allowed actions: Authenticate
+
+ (S) Toggle the sign capability
+ (E) Toggle the encrypt capability
+ (A) Toggle the authenticate capability
+ (Q) Finished
+
+ Your selection? q
+ RSA keys may be between 1024 and 4096 bits long.
+ What keysize do you want? (2048) 4096
+ Requested keysize is 4096 bits
+ Please specify how long the key should be valid.
+ 0 = key does not expire
+ <n> = key expires in n days
+ <n>w = key expires in n weeks
+ <n>m = key expires in n months
+ <n>y = key expires in n years
+ Key is valid for? (0) 0
+ Key does not expire at all
+ Is this correct? (y/N) y
+ Really create? (y/N) y
+ We need to generate a lot of random bytes. It is a good idea to perform
+ some other action (type on the keyboard, move the mouse, utilize the
+ disks) during the prime generation; this gives the random number
+ generator a better chance to gain enough entropy.
+
+ +++++
+ .....+++++
+
+ pub 4096R/0x47FE984F98EE7407 created: 2016-01-30 expires: never usage: SC
+
+ trust: ultimate validity: ultimate
+ sub 4096R/0xE8E7855AA5AE79A7 created: 2016-01-30 expires: never usage: S
+
+ sub 4096R/0x39988E0390CB4B0C created: 2016-01-30 expires: never usage: E
+
+ sub 4096R/0x218BCF996C7A6E31 created: 2016-01-30 expires: never usage: A
+
+ [ultimate] (1). Doctor Duh <drduh@users.noreply.github.com>
+
+ gpg> save
+
+## Check your work
+
+ $ gpg --list-secret-keys
+ /tmp/tmp.eBbMfyVDDt/secring.gpg
+ -------------------------------
+ sec 4096R/0x47FE984F98EE7407 2016-01-30
+ Key fingerprint = 044C ABD0 9043 F1E0 3785 3979 47FE 984F 98EE 7407
+ uid Doctor Duh <drduh@users.noreply.github.com>
+ ssb 4096R/0xE8E7855AA5AE79A7 2016-01-30
+ ssb 4096R/0x39988E0390CB4B0C 2016-01-30
+ ssb 4096R/0x218BCF996C7A6E31 2016-01-30
+
+## Export subkeys
+
+ $ gpg --armor --export-secret-keys 0x47FE984F98EE7407 > $GNUPGHOME/mastersub.key
+
+ $ gpg --armor --export-secret-subkeys 0x47FE984F98EE7407 > $GNUPGHOME/sub.key
+
+## Back up everything
+
+Once keys are moved to hardware, they cannot be extracted again (otherwise, what would be the point?), so make sure you have made a backup before proceeding.
+
+ $ cp -avi $GNUPGHOME /mnt/offline-encrypted-usb/backup/
+
+## Configure YubiKey
+
+ $ ykpersonalize -m82
+ Firmware version 4.2.7 Touch level 527 Program sequence 4
+
+ The USB mode will be set to: 0x82
+
+ Commit? (y/n) [n]: y
+
+>The -m option is the mode command. To see the different modes, enter ykpersonalize –help. Mode 82 (in hex) enables the YubiKey NEO as a composite USB device (HID + CCID) and allows OTPs to be emitted while in use as a smart card. Once you have changed the mode, you need to re-boot the YubiKey – so remove and re-insert it.
+
+https://www.yubico.com/2012/12/yubikey-neo-openpgp/
+
+## Configure smartcard
+
+ $ gpg --card-edit
+
+ Application ID ...: D2760001240102010006055532110000
+ Version ..........: 2.1
+ Manufacturer .....: unknown
+ Serial number ....: 05553211
+ Name of cardholder: [not set]
+ Language prefs ...: [not set]
+ Sex ..............: unspecified
+ URL of public key : [not set]
+ Login data .......: [not set]
+ Private DO 1 .....: [not set]
+ Private DO 2 .....: [not set]
+ Signature PIN ....: not forced
+ Key attributes ...: 2048R 2048R 2048R
+ Max. PIN lengths .: 127 127 127
+ PIN retry counter : 3 3 3
+ Signature counter : 0
+ Signature key ....: [none]
+ Encryption key....: [none]
+ Authentication key: [none]
+ General key info..: [none]
+
+### Change PINs
+
+The default PIN codes are `12345678` and `123456`.
+
+ gpg/card> admin
+ Admin commands are allowed
+
+ gpg/card> passwd
+ gpg: OpenPGP card no. D2760001240102010006055532110000 detected
+
+ 1 - change PIN
+ 2 - unblock PIN
+ 3 - change Admin PIN
+ 4 - set the Reset Code
+ Q - quit
+
+ Your selection? 3
+ PIN changed.
+
+ 1 - change PIN
+ 2 - unblock PIN
+ 3 - change Admin PIN
+ 4 - set the Reset Code
+ Q - quit
+
+ 1 - change PIN
+ 2 - unblock PIN
+ 3 - change Admin PIN
+ 4 - set the Reset Code
+ Q - quit
+
+ Your selection? 1
+ PIN changed.
+
+ 1 - change PIN
+ 2 - unblock PIN
+ 3 - change Admin PIN
+ 4 - set the Reset Code
+ Q - quit
+
+ Your selection? q
+
+### Set optional card information
+
+ gpg/card> name
+ Cardholder's surname: Duh
+ Cardholder's given name: Dr
+
+ gpg/card> lang
+ Language preferences: en
+
+ gpg/card> login
+ Login data (account name): drduh@users.noreply.github.com
+
+ gpg/card>
+
+ Application ID ...: D2760001240102010006055532110000
+ Version ..........: 2.1
+ Manufacturer .....: unknown
+ Serial number ....: 05553211
+ Name of cardholder: Dr Duh
+ Language prefs ...: en
+ Sex ..............: unspecified
+ URL of public key : [not set]
+ Login data .......: drduh@users.noreply.github.com
+ Private DO 4 .....: [not set]
+ Signature PIN ....: not forced
+ Key attributes ...: 2048R 2048R 2048R
+ Max. PIN lengths .: 127 127 127
+ PIN retry counter : 3 3 3
+ Signature counter : 0
+ Signature key ....: [none]
+ Encryption key....: [none]
+ Authentication key: [none]
+ General key info..: [none]
+
+ gpg/card> quit
+
+## Transfer keys
+
+This is a one-way operation only. Make sure you've made a backup before proceeding!
+
+ $ gpg --edit-key 0x47FE984F98EE7407
+ gpg (GnuPG) 1.4.18; Copyright (C) 2014 Free Software Foundation, Inc.
+ This is free software: you are free to change and redistribute it.
+ There is NO WARRANTY, to the extent permitted by law.
+
+ Secret key is available.
+
+ pub 4096R/0x47FE984F98EE7407 created: 2016-01-30 expires: never usage: SC
+
+ trust: ultimate validity: ultimate
+ sub 4096R/0xE8E7855AA5AE79A7 created: 2016-01-30 expires: never usage: S
+
+ sub 4096R/0x39988E0390CB4B0C created: 2016-01-30 expires: never usage: E
+
+ sub 4096R/0x218BCF996C7A6E31 created: 2016-01-30 expires: never usage: A
+
+ [ultimate] (1). Doctor Duh <drduh@users.noreply.github.com>
+
+ gpg> toggle
+
+ sec 4096R/0x47FE984F98EE7407 created: 2016-01-30 expires: never
+ ssb 4096R/0xE8E7855AA5AE79A7 created: 2016-01-30 expires: never
+ ssb 4096R/0x39988E0390CB4B0C created: 2016-01-30 expires: never
+ ssb 4096R/0x218BCF996C7A6E31 created: 2016-01-30 expires: never
+ (1) Doctor Duh <drduh@users.noreply.github.com>
+
+ gpg> key 1
+
+ sec 4096R/0x47FE984F98EE7407 created: 2016-01-30 expires: never
+ ssb* 4096R/0xE8E7855AA5AE79A7 created: 2016-01-30 expires: never
+ ssb 4096R/0x39988E0390CB4B0C created: 2016-01-30 expires: never
+ ssb 4096R/0x218BCF996C7A6E31 created: 2016-01-30 expires: never
+ (1) Doctor Duh <drduh@users.noreply.github.com>
+
+### Signature key
+
+ gpg> keytocard
+ Signature key ....: [none]
+ Encryption key....: [none]
+ Authentication key: [none]
+
+ Please select where to store the key:
+ (1) Signature key
+ (3) Authentication key
+ Your selection? 1
+
+ You need a passphrase to unlock the secret key for
+ user: "Doctor Duh <drduh@users.noreply.github.com>"
+ 4096-bit RSA key, ID 0xE8E7855AA5AE79A7, created 2016-01-30
+
+
+ sec 4096R/0x47FE984F98EE7407 created: 2016-01-30 expires: never
+ ssb* 4096R/0xE8E7855AA5AE79A7 created: 2016-01-30 expires: never
+ card-no: 0006 05553211
+ ssb 4096R/0x39988E0390CB4B0C created: 2016-01-30 expires: never
+ ssb 4096R/0x218BCF996C7A6E31 created: 2016-01-30 expires: never
+ (1) Doctor Duh <drduh@users.noreply.github.com>
+
+### Encryption key
+
+Type `key 1` again to deselect and switch to the next key.
+
+ gpg> key 1
+
+ sec 4096R/0x47FE984F98EE7407 created: 2016-01-30 expires: never
+ ssb 4096R/0xE8E7855AA5AE79A7 created: 2016-01-30 expires: never
+ card-no: 0006 05553211
+ ssb 4096R/0x39988E0390CB4B0C created: 2016-01-30 expires: never
+ ssb 4096R/0x218BCF996C7A6E31 created: 2016-01-30 expires: never
+ (1) Doctor Duh <drduh@users.noreply.github.com>
+
+ gpg> key 2
+
+ sec 4096R/0x47FE984F98EE7407 created: 2016-01-30 expires: never
+ ssb 4096R/0xE8E7855AA5AE79A7 created: 2016-01-30 expires: never
+ card-no: 0006 05553211
+ ssb* 4096R/0x39988E0390CB4B0C created: 2016-01-30 expires: never
+ ssb 4096R/0x218BCF996C7A6E31 created: 2016-01-30 expires: never
+ (1) Doctor Duh <drduh@users.noreply.github.com>
+
+ gpg> keytocard
+ Signature key ....: 04CB BB4B 1D99 3398 A0B1 4C4B E8E7 855A A5AE 79A7
+ Encryption key....: [none]
+ Authentication key: [none]
+
+ Please select where to store the key:
+ (2) Encryption key
+ Your selection? 2
+
+ You need a passphrase to unlock the secret key for
+ user: "Doctor Duh <drduh@users.noreply.github.com>"
+ 4096-bit RSA key, ID 0x39988E0390CB4B0C, created 2016-01-30
+
+
+ sec 4096R/0x47FE984F98EE7407 created: 2016-01-30 expires: never
+ ssb 4096R/0xE8E7855AA5AE79A7 created: 2016-01-30 expires: never
+ card-no: 0006 05553211
+ ssb* 4096R/0x39988E0390CB4B0C created: 2016-01-30 expires: never
+ card-no: 0006 05553211
+ ssb 4096R/0x218BCF996C7A6E31 created: 2016-01-30 expires: never
+ (1) Doctor Duh <drduh@users.noreply.github.com>
+
+### Authentication key
+
+ gpg> key 2
+
+ sec 4096R/0x47FE984F98EE7407 created: 2016-01-30 expires: never
+ ssb 4096R/0xE8E7855AA5AE79A7 created: 2016-01-30 expires: never
+ card-no: 0006 05553211
+ ssb 4096R/0x39988E0390CB4B0C created: 2016-01-30 expires: never
+ card-no: 0006 05553211
+ ssb 4096R/0x218BCF996C7A6E31 created: 2016-01-30 expires: never
+ (1) Doctor Duh <drduh@users.noreply.github.com>
+
+ gpg> key 3
+
+ sec 4096R/0x47FE984F98EE7407 created: 2016-01-30 expires: never
+ ssb 4096R/0xE8E7855AA5AE79A7 created: 2016-01-30 expires: never
+ card-no: 0006 05553211
+ ssb 4096R/0x39988E0390CB4B0C created: 2016-01-30 expires: never
+ card-no: 0006 05553211
+ ssb* 4096R/0x218BCF996C7A6E31 created: 2016-01-30 expires: never
+ (1) Doctor Duh <drduh@users.noreply.github.com>
+
+ gpg> keytocard
+ Signature key ....: 04CB BB4B 1D99 3398 A0B1 4C4B E8E7 855A A5AE 79A7
+ Encryption key....: 8AB0 607B A1C1 0F19 2627 6EA6 3998 8E03 90CB 4B0C
+ Authentication key: [none]
+
+ Please select where to store the key:
+ (3) Authentication key
+ Your selection? 3
+
+ You need a passphrase to unlock the secret key for
+ user: "Doctor Duh <drduh@users.noreply.github.com>"
+ 4096-bit RSA key, ID 0x218BCF996C7A6E31, created 2016-01-30
+
+
+ sec 4096R/0x47FE984F98EE7407 created: 2016-01-30 expires: never
+ ssb 4096R/0xE8E7855AA5AE79A7 created: 2016-01-30 expires: never
+ card-no: 0006 05553211
+ ssb 4096R/0x39988E0390CB4B0C created: 2016-01-30 expires: never
+ card-no: 0006 05553211
+ ssb* 4096R/0x218BCF996C7A6E31 created: 2016-01-30 expires: never
+ card-no: 0006 05553211
+ (1) Doctor Duh <drduh@users.noreply.github.com>
+
+ gpg> save
+
+## Check your work
+
+ gpg --list-secret-keys
+ /tmp/tmp.eBbMfyVDDt/secring.gpg
+ -------------------------------
+ sec 4096R/0x47FE984F98EE7407 2016-01-30
+ Key fingerprint = 044C ABD0 9043 F1E0 3785 3979 47FE 984F 98EE 7407
+ uid Doctor Duh <drduh@users.noreply.github.com>
+ ssb> 4096R/0xE8E7855AA5AE79A7 2016-01-30
+ ssb> 4096R/0x39988E0390CB4B0C 2016-01-30
+ ssb> 4096R/0x218BCF996C7A6E31 2016-01-30
+
+`ssb>` indicates a stub to the private key on smartcard.
+
+## Export public key
+
+ $ gpg --armor --export 0x47FE984F98EE7407 > /mnt/public-usb-key/
+
+# Using keys
+
+## Insert YubiKey
+
+ $ gpg --card-status
+ Application ID ...: D2760001240102010006055532110000
+ Version ..........: 2.1
+ Manufacturer .....: unknown
+ Serial number ....: 05553211
+ Name of cardholder: Dr Duh
+ Language prefs ...: en
+ Sex ..............: unspecified
+ URL of public key : [not set]
+ Login data .......: drduh@users.noreply.github.com
+ Signature PIN ....: not forced
+ Key attributes ...: 4096R 4096R 4096R
+ Max. PIN lengths .: 127 127 127
+ PIN retry counter : 3 3 3
+ Signature counter : 0
+ Signature key ....: 04CB BB4B 1D99 3398 A0B1 4C4B E8E7 855A A5AE 79A7
+ created ....: 2016-01-30 16:36:40
+ Encryption key....: 8AB0 607B A1C1 0F19 2627 6EA6 3998 8E03 90CB 4B0C
+ created ....: 2016-01-30 16:42:29
+ Authentication key: 3B81 E129 B7C3 26F4 2EA1 2F19 218B CF99 6C7A 6E31
+ created ....: 2016-01-30 16:44:48
+ General key info..: pub 4096R/0xE8E7855AA5AE79A7 2016-01-30 Doctor Duh <drduh@users.noreply.github.com>
+ sec# 4096R/0x47FE984F98EE7407 created: 2016-01-30 expires: never
+ ssb> 4096R/0xE8E7855AA5AE79A7 created: 2016-01-30 expires: never
+ card-no: 0006 05553211
+ ssb> 4096R/0x39988E0390CB4B0C created: 2016-01-30 expires: never
+ card-no: 0006 05553211
+ ssb> 4096R/0x218BCF996C7A6E31 created: 2016-01-30 expires: never
+ card-no: 0006 05553211
+
+`sec#` indicates master key is not available (as it should be stored encrypted and offline).
+
+## Import public key
+
+ $ gpg --import < /mnt/public-usb-key/pubkey.txt
+
+## Trust master key
+
+ $ gpg --edit-key 0x47FE984F98EE7407
+ gpg (GnuPG) 1.4.18; Copyright (C) 2014 Free Software Foundation, Inc.
+ This is free software: you are free to change and redistribute it.
+ There is NO WARRANTY, to the extent permitted by law.
+
+ Secret key is available.
+
+ pub 4096R/0x47FE984F98EE7407 created: 2016-01-30 expires: never usage: SC
+
+ trust: unknown validity: unknown
+ sub 4096R/0xE8E7855AA5AE79A7 created: 2016-01-30 expires: never usage: S
+
+ sub 4096R/0x39988E0390CB4B0C created: 2016-01-30 expires: never usage: E
+
+ sub 4096R/0x218BCF996C7A6E31 created: 2016-01-30 expires: never usage: A
+
+ [ unknown] (1). Doctor Duh <drduh@users.noreply.github.com>
+
+ gpg> trust
+ pub 4096R/0x47FE984F98EE7407 created: 2016-01-30 expires: never usage: SC
+
+ trust: unknown validity: unknown
+ sub 4096R/0xE8E7855AA5AE79A7 created: 2016-01-30 expires: never usage: S
+
+ sub 4096R/0x39988E0390CB4B0C created: 2016-01-30 expires: never usage: E
+
+ sub 4096R/0x218BCF996C7A6E31 created: 2016-01-30 expires: never usage: A
+
+ [ unknown] (1). Doctor Duh <drduh@users.noreply.github.com>
+
+ Please decide how far you trust this user to correctly verify other users' keys
+ (by looking at passports, checking fingerprints from different sources, etc.)
+
+ 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
+
+ Your decision? 5
+ Do you really want to set this key to ultimate trust? (y/N) y
+
+ pub 4096R/0x47FE984F98EE7407 created: 2016-01-30 expires: never usage: SC
+
+ trust: ultimate validity: unknown
+ sub 4096R/0xE8E7855AA5AE79A7 created: 2016-01-30 expires: never usage: S
+
+ sub 4096R/0x39988E0390CB4B0C created: 2016-01-30 expires: never usage: E
+
+ sub 4096R/0x218BCF996C7A6E31 created: 2016-01-30 expires: never usage: A
+
+ [ unknown] (1). Doctor Duh <drduh@users.noreply.github.com>
+ Please note that the shown key validity is not necessarily correct
+ unless you restart the program.
+
+ gpg> quit
+
+## GnuPG
+
+### Encryption/decryption
+
+ $ echo "$(uname -a)" | gpg --encrypt --armor -r 0x47FE984F98EE7407 | gpg --debug --decrypt --armor
+
+ Please enter the PIN
+ gpg: encrypted with 4096-bit RSA key, ID 0x39988E0390CB4B0C, created 2016-01-30
+ "Doctor Duh <drduh@users.noreply.github.com>"
+ Linux workstation 3.16.0-4-amd64 #1 SMP Debian 3.16.7-ckt20-1+deb8u3 (2016-01-17) x86_64 GNU/Linux
+
+### Signing
+
+ $ echo "$(uname -a)" | gpg --encrypt --armor --sign -r 0x47FE984F98EE7407
+ gpg: signatures created so far: 0
+
+ Please enter the PIN
+ [sigs done: 0]
+ -----BEGIN PGP MESSAGE-----
+
+ hQIMAzmYjgOQy0sMAQ//bG8YyEinTOFzL/aL/BN54/PAFzBZj6B//dEFXYu5NlHJ
+ [...]
+ sjLN5ZhJkQKJeUWIVdGeuZN+pIeIRWQHeKD7xRUgij6/nC7qCfPPkHFYxQ==
+ =jztu
+ -----END PGP MESSAGE-----
+
+## SSH
+
+### Create configuration
+
+ $ cat > ~/.gnupg/gpg-agent.conf
+ pinentry-program /usr/bin/pinentry-curses
+ default-cache-ttl 60
+ max-cache-ttl 120
+ enable-ssh-support
+ write-env-file
+ use-standard-socket
+ ^D (Press Control-D)
+
+### Replace ssh-agent with gpg-agent
+
+ $ pkill ssh-agent && \
+ eval $(gpg-agent --daemon --enable-ssh-support --use-standard-socket \
+ --log-file ~/.gnupg/gpg-agent.log --write-env-file)
+
+### Copy public key to server
+
+ $ ssh-add -L
+ ssh-rsa AAAAB4NzaC1yc2EAAAADAQABAAACAz[...]zreOKM+HwpkHzcy9DQcVG2Nw== cardno:000605553211
+
+### Connect with public key authentication
+
+ $ ssh git@github.com -vvv
+ [...]
+ debug2: key: cardno:000605553211 (0x1234567890),
+ debug1: Authentications that can continue: publickey
+ debug3: start over, passed a different list publickey
+ debug3: preferred gssapi-keyex,gssapi-with-mic,publickey,keyboard-interactive,password
+ debug3: authmethod_lookup publickey
+ debug3: remaining preferred: keyboard-interactive,password
+ debug3: authmethod_is_enabled publickey
+ debug1: Next authentication method: publickey
+ debug1: Offering RSA public key: cardno:000605553211
+ debug3: send_pubkey_test
+ debug2: we sent a publickey packet, wait for reply
+ debug1: Server accepts key: pkalg ssh-rsa blen 535
+ debug2: input_userauth_pk_ok: fp e5:de:a5:74:b1:3e:96:9b:85:46:e7:28:53:b4:82:c3
+ debug3: sign_and_send_pubkey: RSA e5:de:a5:74:b1:3e:96:9b:85:46:e7:28:53:b4:82:c3
+ debug1: Authentication succeeded (publickey).
+ [...]
+
+# Notes
+
+- Don't write to drduh@users.noreply.github.com, open an issue on GitHub instead.
+- Programming YubiKey for GPG keys still lets you use its two slots - OTP and static password modes, for example.
+- ECC may be preferred to RSA 4096, but the 1.4.x branch of GnuPG does not support it.
+- If you encounter problems, try unplugging and re-inserting your YubiKey. Also try installing and using GnuPG 2.x (`sudo apt-get install gnupg2` and `gpg2`)
+
+# References
+
+<https://developers.yubico.com/yubikey-personalization/>
+
+<https://developers.yubico.com/PGP/Card_edit.html>
+
+<https://blog.josefsson.org/2014/06/23/offline-gnupg-master-key-and-subkeys-on-yubikey-neo-smartcard/>
+
+<https://www.esev.com/blog/post/2015-01-pgp-ssh-key-on-yubikey-neo/>
+
+<https://blog.habets.se/2013/02/GPG-and-SSH-with-Yubikey-NEO>
+
+<https://trmm.net/Yubikey>
+
+<https://rnorth.org/8/gpg-and-ssh-with-yubikey-for-mac>
+
+<https://jclement.ca/articles/2015/gpg-smartcard/>
+
+<https://github.com/herlo/ssh-gpg-smartcard-config>
+
+<http://www.bootc.net/archives/2013/06/09/my-perfect-gnupg-ssh-agent-setup/>
+
+<https://help.riseup.net/en/security/message-security/openpgp/best-practices>