Skip to content

Instantly share code, notes, and snippets.

@masterzen
Last active February 7, 2024 17:02
Show Gist options
  • Save masterzen/107fee1e0064dbc3fadd21707ba44b40 to your computer and use it in GitHub Desktop.
Save masterzen/107fee1e0064dbc3fadd21707ba44b40 to your computer and use it in GitHub Desktop.
Yubikey setup

Yubikey Setup

Preliminary steps

Install software

brew install gpg-suite
brew install yubico-piv-tool
brew install pinentry-mac
brew install yubikey-personalization
brew install openssh

If you want to use GPG, install the Mac GPG Suite:

brew cask install gpg-suite

Setup the key

Management key

Change Management key. The management key is used to reset the key to factory default.

unset HISTFILE
key=`dd if=/dev/random bs=1 count=24 2>/dev/null | hexdump -v -e '/1 "%02X"'`
yubico-piv-tool -a set-mgm-key -n $key --key 010203040506070801020304050607080102030405060708

Change PIV PIN and PUK

The PIN is used to use the authentication or sign function of the yubikey. The admin PIN (or PUK) is used to recover a blocked key if you entered more than 3 invalid PIN. After 3 invalid admin PIN, you need to use the management key.

yubico-piv-tool -a change-pin -P 123456 -N <somethingelse>
yubico-piv-tool -a change-puk -P 12345678 -N <somethingelse>

Setup the GPG applet

Do the same for the GPG applet:

$ gpg --card-edit
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

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

Setup the GPG applet:

gpg/card> name
Cardholder's surname: <Your name>
Cardholder's given name: <Your name>

gpg/card> lang
Language preferences: en

gpg/card> login
Login data (account name): <yourname>

gpg/card> (Press Enter)

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 .......: doc@duh.to
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

U2F for 2FA

The yubikey supports the U2F protocol to use it as a 2FA device on some services when running on Chrome (and probably Firefox with the correct extension). See the available services (including github, dashlane, dropbox, etc) here

Follow the instructions for each provider. Using the key is as simple as touching it when requested.

SSH with FIDO2

This process is better than the PIV version which is mutually exclusive with GPG.

First make sure homebrew openssh is installed, also make sure you also run the hombrew ssh-agent (it is not possible to disable macos ssh-agent anymore, so both have to leave together).

Make sure to add a FIDO pin

ykman fido set-pin

Keep the pin preciously in your password vault.

Generate the key

ssh-keygen -t ecdsa-sk -O resident

Enter the PIN set in the previous step and touch the key.

This will generate the key and leave it into the yubikey. This creates a pub and private file. You can get rid of the private file as it will stay in the key. The pub key should be distributed to the other machines authorized_keys file or github/gitlab.

Use it

To use it, we just need to add it to the agent:

ssh-add -K

Enter the PIN.

(this works only with macos ssh-agent).

SSH with PIV

To use the yubikey to hold your ssh private key:

Generate a new keypair

Note PIV doesn't support 4096 bits keys.

% ssh-keygen -t rsa -b 2048
Generating public/private rsa key pair.
Enter file in which to save the key (/Users/brice/.ssh/id_rsa): /tmp/yubi_rsa
Enter passphrase (empty for no passphrase):
Enter same passphrase again:
Your identification has been saved in /tmp/yubi_rsa.
Your public key has been saved in /tmp/yubi_rsa.pub.
The key fingerprint is:
SHA256:KUUbRkiuSsA6ziODZtVS22eIr1CZTAEp/PlQxK7+CNQ brice@arsenic
The key's randomart image is:
+---[RSA 2048]----+
|.  .=+.o=        |
|.o . +oo o       |
|..o +o. o        |
|...+=o*...       |
|o..E=O.oSo       |
|=o.oo...o        |
|+Bo.   .         |
|+.o.o .          |
|   ..o           |
+----[SHA256]-----+

convert it to yubico-piv-tool pem format:

% openssl rsa -in /tmp/yubi_rsa -out /tmp/yubi_rsa.pem -outform pem

writing RSA key

Import the key to the yubikey

% yubico-piv-tool -aimport-key -k -s9a --touch-policy=always -i /tmp/yubi_rsa.pem

Convert the public key to ssh format:

% ssh-keygen -e -f /tmp/yubi_rsa.pub -m PKCS8 >| /tmp/yubi_rsa.pub.pkcs8

Add the key certificate to the yubikey:

yubico-piv-tool -a verify -a selfsign-certificate -s 9a -S "/CN=brice/O=dow/" -i /tmp/yubi_rsa.pub.pkcs8 -o /tmp/cert.pem
yubico-piv-tool -k -a verify -a import-certificate -s 9a -i /tmp/cert.pem

Test the key

Add the public key to a server ~/.ssh/authorized_keys and test it works:

% ssh -I /opt/boxen/homebrew/opt/opensc/lib/pkcs11/opensc-pkcs11.so brice@server.domain.name
<enter pin>
<touch key>

You can add the yubikey to your agent:

ssh-add -s /opt/boxen/homebrew/opt/opensc/lib/pkcs11/opensc-pkcs11.so
<enter pin>

Then you need to touch the key for every ssh. This is a way to secure ssh forward agent.

Note1: you might need to change the opensc-pkcs11.so path to suit your system. Note2: ssh-agent has a whitelist (see -P), you might need to move the opensc-pkcs11.so library to /usr/local/lib for it to work.

GPG

This is a bit more complex

Prepare the system

Create a temporary GNUPG homedir with secure defaults:

% export GNUPGHOME=$(mktemp -d) ; echo $GNUPGHOME
% cat << EOF > $GNUPGHOME/gpg.conf
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
s2k-cipher-algo AES256
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
EOF

Create Master key

Let's create a 4096 bits master key

% gpg --full-generate-key
gpg (GnuPG) 2.2.1; Copyright (C) 2017 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
                        
GnuPG needs to construct a user ID to identify your key.

Real name: John Doe
Email address: john@doe.xyz
Comment:
You selected this USER-ID:
    "John Doe <john@doe.xyz>"

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

You'll have to enter a passphrase. Make sure to remember it.

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: /var/folders/xp/mfx258x922z4dtyydtf8twg40000gn/T/tmp.gWJlGmS4pn/trustdb.gpg: trustdb created
gpg: key 0xEC9C1870614C3402 marked as ultimately trusted
gpg: directory '/var/folders/xp/mfx258x922z4dtyydtf8twg40000gn/T/tmp.gWJlGmS4pn/openpgp-revocs.d' created
gpg: revocation certificate stored as '/var/folders/xp/mfx258x922z4dtyydtf8twg40000gn/T/tmp.gWJlGmS4pn/openpgp-revocs.d/E9C1CEEF463FA55C03811D71EC9C1870614C3402.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/0xEC9C1870614C3402 2017-12-04 [SC]
      Key fingerprint = E9C1 CEEF 463F A55C 0381  1D71 EC9C 1870 614C 3402
uid                              John Doe <john@doe.xyz>

Keep the keyid

Keep the keyid handy:

export KEYID=0xEC9C1870614C3402

Add more identities (optional)

You can add more identities and/or a picture with adduid:

% gpg --edit-key $KEYID
gpg (GnuPG/MacGPG2) 2.2.0; Copyright (C) 2017 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.

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
sec  rsa4096/0xEC9C1870614C3402
     created: 2017-12-04  expires: never       usage: SC
     trust: ultimate      validity: ultimate
[ultimate] (1). John Doe <john@doe.xyz>

gpg> adduid
Real name: John Doe
Email address: j.doe@unknown.corp
Comment:
You selected this USER-ID:
    "John Doe <j.doe@unknown.corp>"

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

sec  rsa4096/0xEC9C1870614C3402
     created: 2017-12-04  expires: never       usage: SC
     trust: ultimate      validity: ultimate
[ultimate] (1)  John Doe <john@doe.xyz>
[ unknown] (2). John Doe <j.doe@unknown.corp>

gpg> save

Sign with an older key (optional)

This is now a good time to sign this key if you already had one.

% gpg -u 0xOLDKEYID --sign-key $KEYID

Create Subkeys

Let's edit the key

% gpg --expert --edit-key $KEYID
gpg (GnuPG/MacGPG2) 2.2.0; Copyright (C) 2017 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.

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
sec  rsa4096/0xEC9C1870614C3402
     created: 2017-12-04  expires: never       usage: SC
     trust: ultimate      validity: ultimate
[ultimate] (1). John Doe <j.doe@unknown.corp>
[ultimate] (2)  John Doe <john@doe.xyz>

Create a signing key

gpg> addkey
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)
  (10) ECC (sign only)
  (11) ECC (set your own capabilities)
  (12) ECC (encrypt only)
  (13) Existing key
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.

sec  rsa4096/0xEC9C1870614C3402
     created: 2017-12-04  expires: never       usage: SC
     trust: ultimate      validity: ultimate
ssb  rsa4096/0x7992F277C72B3AA7
     created: 2017-12-04  expires: never       usage: S
[ultimate] (1). John Doe <j.doe@unknown.corp>
[ultimate] (2)  John Doe <john@doe.xyz>

Create an encryption key

gpg> addkey
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)
  (10) ECC (sign only)
  (11) ECC (set your own capabilities)
  (12) ECC (encrypt only)
  (13) Existing key
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.

sec  rsa4096/0xEC9C1870614C3402
     created: 2017-12-04  expires: never       usage: SC
     trust: ultimate      validity: ultimate
ssb  rsa4096/0x7992F277C72B3AA7
     created: 2017-12-04  expires: never       usage: S
ssb  rsa4096/0xC4BA9434EE89ACBB
     created: 2017-12-04  expires: never       usage: E
[ultimate] (1). John Doe <j.doe@unknown.corp>
[ultimate] (2)  John Doe <john@doe.xyz>

Create an authentication key

There's no authenticate default, so choose 8, and deselect Sign and Encrypt then select Authenticate.

gpg> addkey
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)
  (10) ECC (sign only)
  (11) ECC (set your own capabilities)
  (12) ECC (encrypt only)
  (13) Existing key
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.

sec  rsa4096/0xEC9C1870614C3402
     created: 2017-12-04  expires: never       usage: SC
     trust: ultimate      validity: ultimate
ssb  rsa4096/0x7992F277C72B3AA7
     created: 2017-12-04  expires: never       usage: S
ssb  rsa4096/0xC4BA9434EE89ACBB
     created: 2017-12-04  expires: never       usage: E
ssb  rsa4096/0xEE9A1CDDB09023DA
     created: 2017-12-04  expires: never       usage: A
[ultimate] (1). John Doe <j.doe@unknown.corp>
[ultimate] (2)  John Doe <john@doe.xyz>

Check

% gpg --list-secret-keys
/var/folders/xp/mfx258x922z4dtyydtf8twg40000gn/T/tmp.gWJlGmS4pn/pubring.kbx
---------------------------------------------------------------------------
sec   rsa4096/0xEC9C1870614C3402 2017-12-04 [SC]
      Key fingerprint = E9C1 CEEF 463F A55C 0381  1D71 EC9C 1870 614C 3402
uid                   [ultimate] John Doe <j.doe@unknown.corp>
uid                   [ultimate] John Doe <john@doe.xyz>
ssb   rsa4096/0x7992F277C72B3AA7 2017-12-04 [S]
ssb   rsa4096/0xC4BA9434EE89ACBB 2017-12-04 [E]
ssb   rsa4096/0xEE9A1CDDB09023DA 2017-12-04 [A]

Save a copy

% gpg --armor --export-secret-keys $KEYID > $GNUPGHOME/mastersub.key

% gpg --armor --export-secret-subkeys $KEYID > $GNUPGHOME/sub.key

The mastersub.key is protected by the original passphrase you chose.

Keep also the recovery certificate.

Backup everything

Once the keys are in the yubikey it is not possible to recover them. The best is to backup them to an encrypted storage (USB drive encrypted for instance, either LUKS on Linux, File Vault encrypted on OSX, or using VeraCrypt)

Transfer keys to the yubikey

% gpg --edit-key $KEYID
gpg (GnuPG/MacGPG2) 2.2.0; Copyright (C) 2017 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.

sec  rsa4096/0xEC9C1870614C3402
     created: 2017-12-04  expires: never       usage: SC
     trust: ultimate      validity: ultimate
ssb  rsa4096/0x7992F277C72B3AA7
     created: 2017-12-04  expires: never       usage: S
ssb  rsa4096/0xC4BA9434EE89ACBB
     created: 2017-12-04  expires: never       usage: E
ssb  rsa4096/0xEE9A1CDDB09023DA
     created: 2017-12-04  expires: never       usage: A
[ultimate] (1). John Doe <j.doe@unknown.corp>
[ultimate] (2)  John Doe <john@doe.xyz>

Transfer the signature key

gpg> key 1

sec  rsa4096/0xEC9C1870614C3402
     created: 2017-12-04  expires: never       usage: SC
     trust: ultimate      validity: ultimate
ssb* rsa4096/0x7992F277C72B3AA7
     created: 2017-12-04  expires: never       usage: S
ssb  rsa4096/0xC4BA9434EE89ACBB
     created: 2017-12-04  expires: never       usage: E
ssb  rsa4096/0xEE9A1CDDB09023DA
     created: 2017-12-04  expires: never       usage: A
[ultimate] (1). John Doe <j.doe@unknown.corp>
[ultimate] (2)  John Doe <john@doe.xyz>

gpg> keytocard
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: "John Doe <john@doe.xyz>"
4096-bit RSA key, ID 0x7992F277C72B3AA7, created 2017-12-04

Transfer the encryption key

You need to deselect the first key first.

gpg> key 1
...
gpg> key 2

sec  rsa4096/0xEC9C1870614C3402
     created: 2017-12-04  expires: never       usage: SC
     trust: ultimate      validity: ultimate
ssb> rsa4096/0x7992F277C72B3AA7
     created: 2017-12-04  expires: never       usage: S
ssb*  rsa4096/0xC4BA9434EE89ACBB
     created: 2017-12-04  expires: never       usage: E
ssb  rsa4096/0xEE9A1CDDB09023DA
     created: 2017-12-04  expires: never       usage: A
[ultimate] (1). John Doe <j.doe@unknown.corp>
[ultimate] (2)  John Doe <john@doe.xyz>

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

Transfer the authentication key

gpg> key 2
...
gpg> key 3

sec  rsa4096/0xEC9C1870614C3402
     created: 2017-12-04  expires: never       usage: SC
     trust: ultimate      validity: ultimate
ssb> rsa4096/0x7992F277C72B3AA7
     created: 2017-12-04  expires: never       usage: S
ssb*  rsa4096/0xC4BA9434EE89ACBB
     created: 2017-12-04  expires: never       usage: E
ssb  rsa4096/0xEE9A1CDDB09023DA
     created: 2017-12-04  expires: never       usage: A
[ultimate] (1). John Doe <j.doe@unknown.corp>
[ultimate] (2)  John Doe <john@doe.xyz>

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

Save

gpg> save

Check

% gpg --list-secret-keys $KEYID
sec   rsa4096/0xEC9C1870614C3402 2017-12-04 [SC]
      Key fingerprint = E9C1 CEEF 463F A55C 0381  1D71 EC9C 1870 614C 3402
uid                   [ultimate] John Doe <j.doe@unknown.corp>
uid                   [ultimate] John Doe <john@doe.xyz>
ssb>  rsa4096/0x7992F277C72B3AA7 2017-12-04 [S]
ssb>  rsa4096/0xC4BA9434EE89ACBB 2017-12-04 [E]
ssb>  rsa4096/0xEE9A1CDDB09023DA 2017-12-04 [A]

The > in the ssb> means the key has been moved to a smartcard.

Export your public key

So that other people can encrypt content to you or verify your signature.

$ gpg --armor --export $KEYID > pubkey.txt

Alternatively publish the key to a keyserver:

$ gpg --send-key $KEYID
...

You can also add the key to your keybase.io account.

Cleanup

Now you can securely remove the $GNUPGHOME directory (or reboot the mac).

Use your GPG keys

Setup

% cat << EOF > ~/.gnupg/gpg.conf
auto-key-locate keyserver
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-cipher-algo AES256
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
use-agent
require-cross-certification
EOF

% cat << EOF > ~/.gnupg/scdaemon.conf
shared-access
EOF

Import your public key in your keyring

$ gpg --import < pubkey.txt
gpg: key 0xEC9C1870614C3402: public key "John Doe <joe@doe.xyz>" imported
gpg: Total number processed: 1
gpg:               imported: 1  (RSA: 1)

or from the keyserver:

$ gpg --recv 0xEC9C1870614C3402
gpg: requesting key 0xEC9C1870614C3402 from hkps server hkps.pool.sks-keyservers.net
[...]
gpg: key 0xEC9C1870614C3402: public key "John Doe <joe@doe.xyz>" imported
gpg: Total number processed: 1
gpg:               imported: 1  (RSA: 1)

Use the yubikey

Unplug and replug the yubikey, then issue

% gpg --card-status

Reader ...........: Yubico Yubikey 4 OTP U2F CCID
Application ID ...: D2760001240102010006064440590000
Version ..........: 2.1
Manufacturer .....: Yubico
Serial number ....: 06444059
Name of cardholder: John Dow
Language prefs ...: en
Sex ..............: unspecified
URL of public key : [not set]
Login data .......: john
Signature PIN ....: not forced
Key attributes ...: rsa4096 rsa4096 rsa4096
Max. PIN lengths .: 127 127 127
PIN retry counter : 3 0 3
Signature counter : 2
Signature key ....: EE90 42BA AE8C 7B9B BB3F  007B 7992 F277 C72B 3AA7
      created ....: 2017-12-04 20:27:06
Encryption key....: DC21 2F67 E89F EEA9 AB51  58B5 C4BA 9434 EE89 ACBB
      created ....: 2017-12-04 20:27:34
Authentication key: 3FF8 92AD 9C29 548B EC4E  65A9 EE9A 1CDD B090 23DA
      created ....: 2017-12-04 20:28:04
General key info..: sub  rsa4096/0x7992F277C72B3AA7 2017-12-04 John Doe <john@doe.xyz>
sec   rsa4096/0xEC9C1870614C3402  created: 2017-12-04  expires: never
ssb>  rsa4096/0x7992F277C72B3AA7  created: 2017-12-04  expires: never
                                  card-no: 0006 06444059
ssb>  rsa4096/0xC4BA9434EE89ACBB  created: 2017-12-04  expires: never
                                  card-no: 0006 06444059
ssb>  rsa4096/0xEE9A1CDDB09023DA  created: 2017-12-04  expires: never
                                  card-no: 0006 06444059```

If it doesn't work, PIV OpenSC might have locked the card if you added it in your ssh-agent. So first remove it from the agent:

% ssh-add -e /usr/local/lib/opensc-pkcs11.so
Card removed: /usr/local/lib/opensc-pkcs11.so

If it still doesn't work, a gpg scdaemon might still be running from the temporary gnupg homedir. Reboot the computer (or try a gpgconf --kill scdaemon)

Trust your key

Trust ultimately the key (it is yours you can trust it)

% gpg --edit-key 0xEC9C1870614C3402
gpg (GnuPG/MacGPG2) 2.2.0; Copyright (C) 2017 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.


pub  rsa4096/0xEC9C1870614C3402
     created: 2017-12-04  expires: never       usage: SC
     trust: unknown       validity: unknown
sub  rsa4096/0x7992F277C72B3AA7
     created: 2017-12-04  expires: never       usage: S
sub  rsa4096/0xC4BA9434EE89ACBB
     created: 2017-12-04  expires: never       usage: E
sub  rsa4096/0xEE9A1CDDB09023DA
     created: 2017-12-04  expires: never       usage: A
[ unknown] (1). John Doe <j.doe@unknown.corp>
[ unknown] (2)  John Doe <john@doe.xyz>

gpg> trust
pub  rsa4096/0xEC9C1870614C3402
     created: 2017-12-04  expires: never       usage: SC
     trust: unknown       validity: unknown
sub  rsa4096/0x7992F277C72B3AA7
     created: 2017-12-04  expires: never       usage: S
sub  rsa4096/0xC4BA9434EE89ACBB
     created: 2017-12-04  expires: never       usage: E
sub  rsa4096/0xEE9A1CDDB09023DA
     created: 2017-12-04  expires: never       usage: A
[ unknown] (1). John Doe <j.doe@unknown.corp>
[ unknown] (2)  John Doe <john@doe.xyz>

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  rsa4096/0xEC9C1870614C3402
     created: 2017-12-04  expires: never       usage: SC
     trust: ultimate      validity: unknown
sub  rsa4096/0x7992F277C72B3AA7
     created: 2017-12-04  expires: never       usage: S
sub  rsa4096/0xC4BA9434EE89ACBB
     created: 2017-12-04  expires: never       usage: E
sub  rsa4096/0xEE9A1CDDB09023DA
     created: 2017-12-04  expires: never       usage: A
[ unknown] (1). John Doe <j.doe@unknown.corp>
[ unknown] (2)  John Doe <john@doe.xyz>

Please note that the shown key validity is not necessarily correct
unless you restart the program.

gpg> quit

The key is now trusted.

Test Encryption & Decryption

Encrypt something with our encryption key:

% echo "blah blah" | gpg --encrypt --armor --recipient 0xC4BA9434EE89ACBB | pbcopy

And decrypt it (which requires entering your PIN):

% pbpaste | 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 0xC4BA9434EE89ACBB, created
2017-12-04
      "John Doe <john@doe.xyz>"

(Press Control-D)

blah blah

Signature

Let's sign a message with our signing key (this requires entering your PIN):

% echo "blah blah" | gpg --armor --clearsign --default-key 0x7992F277C72B3AA7
gpg: using "0x7992F277C72B3AA7" as default secret key for signing
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA512

blah blah
-----BEGIN PGP SIGNATURE-----

iQIzBAEBCgAdFiEEtDZDtxTSRCt3y6DEQt8oMebgFH4FAlomX7UACgkQQt8oMebg
FH6K8A/+MUqubKc+LzpmQ6f8ywbZx3UbX6I7XEu4qXZiD23Qm3SbLzK4SDf6LCCt
R/oWR46upE8NDub1ByEg5PIIH779OL3n7gQ+/7QEt+vniS9iKlJ3DlsC4Yj+VqEF
SA0ijuU6SOcYa05UXTJNaNiU+t1Mvzed2Kin0r2cvP2dbtkc5GUuWIX6eEGaZLsV
JK1/jlBbPTsvCPQgyhjC7t5sdOBhrNapk27Ig+syftDYs8u0V9Q2LlRs9D7W9fUk
BXvFHBe29GahJdcZfn5pwxQakGvaUOwzkM4eZxeoUgqBZczN6v+MKEjjN5mxv1TL
nVwxN2eENyIAIBHlubcZHhWL6eYRNarKI912s9GmmS1QIlnmShB6+czn9tohMCMh
jUfm7rFP2EUeCb9LQdXygan3796+6kJM6wA/J+6QJpToGjYWYv6D04PUGf40XMNn
s661bakvHFAx2vGYwUHd/YFDb+2bWN7NA0KZWlzqC3nMXnTnwj6H2y9Ko1nq1Tcu
AhNI6kDfkGi9DIhbryfbd3XCbCArPpYzalKiOfssGf9R/R4A67Oal7c+BKl2CjdG
SBcCK7R8YB7WcsMbV+J+ml+KHEv9NMH2DCiU4gaWbq2At4bjUHpnktlNC2vKnW2C
8vksgCHwvqV9tDO+ac6B4fFQPNPlYGSEF79AGzD27qRj6bINhCM=
=rZjI
-----END PGP SIGNATURE-----

And verify the signature by pasting it into gpg (make sure to press CTRL-D at the end):

% gpg
gpg: WARNING: no command supplied.  Trying to guess what you mean ...
gpg: Go ahead and type your message ...
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA512

blah blah
-----BEGIN PGP SIGNATURE-----

iQIzBAEBCgAdFiEEtDZDtxTSRCt3y6DEQt8oMebgFH4FAlomX7UACgkQQt8oMebg
FH6K8A/+MUqubKc+LzpmQ6f8ywbZx3UbX6I7XEu4qXZiD23Qm3SbLzK4SDf6LCCt
R/oWR46upE8NDub1ByEg5PIIH779OL3n7gQ+/7QEt+vniS9iKlJ3DlsC4Yj+VqEF
SA0ijuU6SOcYa05UXTJNaNiU+t1Mvzed2Kin0r2cvP2dbtkc5GUuWIX6eEGaZLsV
JK1/jlBbPTsvCPQgyhjC7t5sdOBhrNapk27Ig+syftDYs8u0V9Q2LlRs9D7W9fUk
BXvFHBe29GahJdcZfn5pwxQakGvaUOwzkM4eZxeoUgqBZczN6v+MKEjjN5mxv1TL
nVwxN2eENyIAIBHlubcZHhWL6eYRNarKI912s9GmmS1QIlnmShB6+czn9tohMCMh
jUfm7rFP2EUeCb9LQdXygan3796+6kJM6wA/J+6QJpToGjYWYv6D04PUGf40XMNn
s661bakvHFAx2vGYwUHd/YFDb+2bWN7NA0KZWlzqC3nMXnTnwj6H2y9Ko1nq1Tcu
AhNI6kDfkGi9DIhbryfbd3XCbCArPpYzalKiOfssGf9R/R4A67Oal7c+BKl2CjdG
SBcCK7R8YB7WcsMbV+J+ml+KHEv9NMH2DCiU4gaWbq2At4bjUHpnktlNC2vKnW2C
8vksgCHwvqV9tDO+ac6B4fFQPNPlYGSEF79AGzD27qRj6bINhCM=
=rZjI
-----END PGP SIGNATURE-----

(press ^D)
blah blah

gpg: Signature made Tue Dec  5 09:58:29 2017 CET
gpg:                using RSA key EE9042BAAE8C7B9BBB3F007B7992F277C72B3AA7
gpg: Good signature from "John Doe <john@doe.xyz>" [full]
gpg:                 aka "John Doe <j.doe@unknown.corp>" [full]
Primary key fingerprint: 1DF4 7E24 3F16 E2A4 5668  A78F 79C7 AD77 3EDD E696
     Subkey fingerprint: EE90 42BA AE8C 7B9B BB3F  007B 7992 F277 C72B 3AA7

Requiring a touch

It is possible to require a key touch to decrypt or sign:

ykman openpgp touch sig on
ykman openpgp touch enc on

Next Steps

Send the key to keybase

If you're not a keybase user, go check it at keybase.io

% keybase pgp select

Sign your Git commits/push/tags

See Git Signing

macOS login

It is possible to require a yubikey to get root access on a local mac. This is possible because the yubikey supports HMAC-SHA1 challenge response.

See the configuration steps here

It is also possible to completely login with a yubikey

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment