Using GPG with Yubikey for SSH Authentication¶
https://www.esev.com/blog/post/2015-01-pgp-ssh-key-on-yubikey-neo/
https://www.isi.edu/~calvin/yubikeyssh.htm
https://rnorth.org/gpg-and-ssh-with-yubikey-for-mac
Install latest gpgtools (MAC)¶
brew cask install gpgtools-beta
Backup existing .gnupg directory and create a new one¶
cd ~
mv .gnupg .gnupg.ori
mkdir .gnupg
cd ~/.gnupg
Create a new gpg.conf file¶
cat >gpg.conf <<EOF
use-agent
personal-cipher-preferences AES256 AES192 AES CAST5
personal-digest-preferences SHA512 SHA384 SHA256 SHA224
cert-digest-algo SHA512
default-preference-list SHA512 SHA384 SHA256 SHA224 AES256 AES192 AES CAST5 ZLIB BZIP2 ZIP Uncompressed
EOF
Generate PGP keys¶
Master Key and Subkeys¶
Your PGP key consists of a master key and one or many subkeys. The master key will be used to CERTIFY (or sign) your subkeys. The subkeys can be configured for one or multiple actions: ENCRYPT, AUTHENTICATE, or SIGN. (A signing subkey means to sign data, as opposed to other keys).
$ gpg --expert --gen-key
gpg (GnuPG/MacGPG2) 2.0.30; Copyright (C) 2015 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)
(7) DSA (set your own capabilities)
(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
Possible actions for a RSA key: Sign Certify Encrypt Authenticate
Current allowed actions: Certify 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 Certify Encrypt Authenticate
Current allowed actions: Certify
(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)
Requested keysize is 2048 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) 2y
Key expires at Thu Sep 5 22:13:22 2019 PDT
Is this correct? (y/N) y
GnuPG needs to construct a user ID to identify your key.
Real name: Jeeva Kailasam
Email address: jkailasam@netflix.com
Comment:
You selected this USER-ID:
"Jeeva Kailasam <jkailasam@netflix.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: key 2D4279A7 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
gpg: next trustdb check due at 2019-09-06
pub 2048R/2D4279A7 2017-09-06 [expires: 2019-09-06]
Key fingerprint = 90E1 809C 3036 2921 1C30 0BC9 7978 2126 2D42 79A7
uid [ultimate] Jeeva Kailasam <jkailasam@netflix.com>
Verify the key¶
$ gpg --list-keys
/Users/jkailasam/.gnupg/pubring.gpg
-----------------------------------
pub 2048R/2D4279A7 2017-09-06 [expires: 2019-09-06]
uid [ultimate] Jeeva Kailasam <jkailasam@netflix.com>
Create a text backup of master key¶
gpg -a --export-secret-keys 2D4279A7 > masterkeys.txt
Generate the revocation Certificate for the master key¶
$ gpg --gen-revoke 2D4279A7 > 2D4279A7.revoke-cert.asc
sec 2048R/2D4279A7 2017-09-06 Jeeva Kailasam <jkailasam@netflix.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? 3
Enter an optional description; end it with an empty line:
>
Reason for revocation: Key is no longer used
(No description given)
Is this okay? (y/N) y
You need a passphrase to unlock the secret key for
user: "Jeeva Kailasam <jkailasam@netflix.com>"
2048-bit RSA key, ID 2D4279A7, created 2017-09-06
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!
Generate Authenticate Subkey¶
Note: NEO limits the subkey size to 2048 bits or less. It is recommended to use 2048bit sub key.
$ gpg --expert --edit-key 2D4279A7
gpg (GnuPG/MacGPG2) 2.0.30; Copyright (C) 2015 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 2048R/2D4279A7 created: 2017-09-06 expires: 2019-09-06 usage: C
trust: ultimate validity: ultimate
[ultimate] (1). Jeeva Kailasam <jkailasam@netflix.com>
gpg> addkey
Key is protected.
You need a passphrase to unlock the secret key for
user: "Jeeva Kailasam <jkailasam@netflix.com>"
2048-bit RSA key, ID 2D4279A7, created 2017-09-06
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)
Requested keysize is 2048 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) 2y
Key expires at Thu Sep 5 22:28:22 2019 PDT
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 2048R/2D4279A7 created: 2017-09-06 expires: 2019-09-06 usage: C
trust: ultimate validity: ultimate
sub 2048R/82166A94 created: 2017-09-06 expires: 2019-09-06 usage: A
[ultimate] (1). Jeeva Kailasam <jkailasam@netflix.com>
gpg> save
export secret subkey for backup¶
gpg -a --export-secret-subkeys 2D4279A7 > subkeys.txt
Configure Yubi Key¶
Make sure Yubikey is plugged in and if gpg2 can read it:
$ gpg --card-status
Reader ...........: Yubico Yubikey 4 OTP U2F CCID
Application ID ...: D2760001240102010006057641800000
Version ..........: 2.1
Manufacturer .....: Yubico
Serial number ....: 05764180
Name of cardholder: [not set]
Language prefs ...: [not set]
Sex ..............: unspecified
URL of public key : [not set]
Login data .......: [not set]
Signature PIN ....: not forced
Key attributes ...: rsa2048 rsa2048 rsa2048
Max. PIN lengths .: 127 127 127
PIN retry counter : 3 0 3
Signature counter : 0
Signature key ....: [none]
Encryption key....: [none]
Authentication key: [none]
General key info..: [none]
Change the PIN and Admin PIN from its defaults (123456 and 12345678 respectively)¶
Admin PIN Lockout: If you incorrectly enter your Admin PIN THREE (3) TIMES, you will be locked out of your YubiKey and it will be useless. You can completely reset your Yubikey if locked out with ResetApplet.
$ gpg --card-edit
gpg/card> admin
Admin commands are allowed
gpg/card> passwd
gpg: OpenPGP card no. XXXXXX detected
1 - change PIN
2 - unblock PIN
3 - change Admin PIN
4 - set the Reset Code
Q - quit
Your selection? 3
PIN changed.
...
Your selection? 1
PIN changed.
...
Your selection? q
gpg/card> quit
Copy the key to the Yubikey¶
$ gpg --edit-key 2D4279A7
gpg (GnuPG/MacGPG2) 2.0.30; Copyright (C) 2015 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 2048R/2D4279A7 created: 2017-09-06 expires: 2019-09-06 usage: C
trust: ultimate validity: ultimate
sub 2048R/82166A94 created: 2017-09-06 expires: 2019-09-06 usage: A
[ultimate] (1). Jeeva Kailasam <jkailasam@netflix.com>
gpg> toggle
sec 2048R/2D4279A7 created: 2017-09-06 expires: 2019-09-06
ssb 2048R/82166A94 created: 2017-09-06 expires: never
(1) Jeeva Kailasam <jkailasam@netflix.com>
gpg> key 1
sec 2048R/2D4279A7 created: 2017-09-06 expires: 2019-09-06
ssb* 2048R/82166A94 created: 2017-09-06 expires: never
(1) Jeeva Kailasam <jkailasam@netflix.com>
gpg> keytocard
Signature key ....: [none]
Encryption key....: [none]
Authentication key: 90F4 9D32 8CAF C26C 3A40 AC46 D26F 240B C525 26BC
Please select where to store the key:
(3) Authentication key
Your selection? 3
gpg: WARNING: such a key has already been stored on the card!
Replace existing key? (y/N) y
You need a passphrase to unlock the secret key for
user: "Jeeva Kailasam <jkailasam@netflix.com>"
2048-bit RSA key, ID 82166A94, created 2017-09-06
sec 2048R/2D4279A7 created: 2017-09-06 expires: 2019-09-06
ssb* 2048R/82166A94 created: 2017-09-06 expires: never
card-no: 0006 05764180
(1) Jeeva Kailasam <jkailasam@netflix.com>
gpg> save
Verify the key is in the card¶
$ gpg --card-status
Application ID ...: D2760001240102010006057641800000
Version ..........: 2.1
Manufacturer .....: Yubico
Serial number ....: 05764180
Name of cardholder: [not set]
Language prefs ...: [not set]
Sex ..............: unspecified
URL of public key : [not set]
Login data .......: [not set]
Signature PIN ....: not forced
Key attributes ...: 2048R 2048R 2048R
Max. PIN lengths .: 127 127 127
PIN retry counter : 3 0 3
Signature counter : 0
Signature key ....: [none]
Encryption key....: [none]
Authentication key: A5BF C8C8 8555 882E 7675 E3BF 2FAA D173 8216 6A94
created ....: 2017-09-06 05:27:49
General key info..: sub 2048R/82166A94 2017-09-06 Jeeva Kailasam <jkailasam@netflix.com>
sec 2048R/2D4279A7 created: 2017-09-06 expires: 2019-09-06
ssb> 2048R/82166A94 created: 2017-09-06 expires: 2019-09-06
card-no: 0006 05764180
Create SSH Pub Key for the subkey¶
$ gpgkey2ssh 82166A94 > id_rsa_jkailasam.pub
Note: If gpgkey2ssh command is not found on the system (MAC), install using
$ brew cask install gpgtools
Create gnupg.conf file¶
cat > ~/.gnupg/gpg-agent.conf <<EOF
pinentry-program /usr/local/MacGPG2/libexec/pinentry-mac.app/Contents/MacOS/pinentry-mac
enable-ssh-support
write-env-file
use-standard-socket
default-cache-ttl 600
max-cache-ttl 7200
debug-level advanced
log-file /tmp/gpg-agent.log
EOF
Append to your ~/.bashrc (or your favorite shell config):¶
if [ -f "${HOME}/.gpg-agent-info" ]; then
. "${HOME}/.gpg-agent-info"
export GPG_AGENT_INFO
export SSH_AUTH_SOCK
fi
export GPG_TTY=$(tty)
How Copy the subkey to second Yubikey¶
gpg> keytocard
Signature key ....: [none]
Encryption key....: [none]
Authentication key: [none]
Please select where to store the key:
(3) Authentication key
Your selection? 3
gpg: secret key already stored on a card
ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDU+8eZt4PdcYbWRPiojMsVHVGxr/bUar93yHe+fQUTpjXvAq56bMQO+bsTC3ZR20MtR1wU74v6Iz9ON6iZdijy4p0rgB7Oj6I7kVzYWy0n+UIyDriLwlcOWinSlvlxZx2CyeJuh1IP/sYgB0jV4JXGiaNH9wZJxpepfC0vLuF9Ip9JwtdOGQtYAAbngtvXPZqnAwAaq4L9AKS6CiA5kRLIkSOW3vx1n7ZmoMpClPU69y2jTWNuueoaBUSaHkgV/5EwDr3cN3KJTfmd0n/b91GengFD4ZyPOlYtXZoCcVAdzesiBHb3QgXDcmwhmb0HoC0ZhbFab/9axFcA5j2yoL+/ COMMENT
$ gpg --delete-secret-keys 82166A94
gpg (GnuPG/MacGPG2) 2.0.30; Copyright (C) 2015 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.
sec 2048R/2D4279A7 2017-09-06 Jeeva Kailasam <jkailasam@netflix.com>
Delete this key from the keyring? (y/N) y
This is a secret key! - really delete? (y/N) y
$ gpg --import subkeys.txt
gpg: key 2D4279A7: secret key imported
gpg: key 2D4279A7: "Jeeva Kailasam <jkailasam@netflix.com>" not changed
gpg: Total number processed: 1
gpg: unchanged: 1
gpg: secret keys read: 1
gpg: secret keys imported: 1
$ gpg --edit-key 2D4279A7
gpg (GnuPG/MacGPG2) 2.0.30; Copyright (C) 2015 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 2048R/2D4279A7 created: 2017-09-06 expires: 2019-09-06 usage: C
trust: ultimate validity: ultimate
sub 2048R/82166A94 created: 2017-09-06 expires: 2019-09-06 usage: A
[ultimate] (1). Jeeva Kailasam <jkailasam@netflix.com>
gpg> toggle
sec 2048R/2D4279A7 created: 2017-09-06 expires: 2019-09-06
ssb 2048R/82166A94 created: 2017-09-06 expires: never
(1) Jeeva Kailasam <jkailasam@netflix.com>
gpg> key 1
sec 2048R/2D4279A7 created: 2017-09-06 expires: 2019-09-06
ssb* 2048R/82166A94 created: 2017-09-06 expires: never
(1) Jeeva Kailasam <jkailasam@netflix.com>
gpg> keytocard
Signature key ....: [none]
Encryption key....: [none]
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: "Jeeva Kailasam <jkailasam@netflix.com>"
2048-bit RSA key, ID 82166A94, created 2017-09-06
sec 2048R/2D4279A7 created: 2017-09-06 expires: 2019-09-06
ssb* 2048R/82166A94 created: 2017-09-06 expires: never
card-no: 0006 06251774
(1) Jeeva Kailasam <jkailasam@netflix.com>
gpg> save
$ gpg --card-status
Application ID ...: D2760001240102010006062517740000
Version ..........: 2.1
Manufacturer .....: Yubico
Serial number ....: 06251774
Name of cardholder: [not set]
Language prefs ...: [not set]
Sex ..............: unspecified
URL of public key : [not set]
Login data .......: [not set]
Signature PIN ....: not forced
Key attributes ...: 2048R 2048R 2048R
Max. PIN lengths .: 127 127 127
PIN retry counter : 3 0 3
Signature counter : 0
Signature key ....: [none]
Encryption key....: [none]
Authentication key: A5BF C8C8 8555 882E 7675 E3BF 2FAA D173 8216 6A94
created ....: 2017-09-06 05:27:49
General key info..: sub 2048R/82166A94 2017-09-06 Jeeva Kailasam <jkailasam@netflix.com>
sec# 2048R/2D4279A7 created: 2017-09-06 expires: 2019-09-06
ssb> 2048R/82166A94 created: 2017-09-06 expires: 2019-09-06
card-no: 0006 06251774