1 Pretty good (Getting Started)
To get started, check to see if your favorite Operating system is up to date. When at all possible, you should always keep current on the latest security patches as a best practice.
# Command to list updates
softwareupdate --list
# Command to install updates
softwareupdate --install --recommended
# Commands to install updates
sudo apt-get update ; wait ; sudo apt-get --upgrade-only dist-upgrade
# Any other update steps go here (like file integrity scans)
Mac users will also need a package manager like brew to install packages later
# install brew if not done so already (for complete directions see http://brew.sh)
which brew || xcode-select –install && ruby -e "$(curl -fsSL --tlsv1.2 --url https://raw.githubusercontent.com/Homebrew/install/master/install)"
brew update
For this blog I tested with a Yubikey 4, because it was on hand, but there are other great PKCS11 cards out there. For expert readers who choose another card you might be able to just skip the parts on the Yubico software and use the equivalent software for the card of choice but be warned secure cards are not forgiving by nature.
If you're new to the whole smart card thing I recommend you try the Yubikey Neo or Yubikey 4, they're easy to find on amazon and relatively easy to use, plus what this blog will focus on.
First install MacGPG, GPG Services, & GPG Keychain (and any other GPG extras you want) from https://gpgtools.org
The steps needed for our use-case are as follows:
1. download the GPG Tools from https://gpgtools.org
2. Run the installer to install MacGPG, GPG Services, & GPG Keychain (and any other GPG extras you want)
To do this via the CLI (latest version was '2016.07_v2' as of July 2016):
# this takes some time:
curl -fsSL --tlsv1.2 --url https://releases.gpgtools.org/GPG_Suite-2016.07_v2.dmg --out /tmp/GPG_Suite.dmg
hdiutil attach /tmp/GPG_Suite.dmg -mountPoint /Volumes/GPG_Suite
# must be admin user to install:
installer -store -pkg /Volumes/GPG_Suite/Install.pkg -target /
wait ; sync ; wait ;
hdiutil detach /Volumes/GPG_Suite || hdiutil detach /Volumes/GPG_Suite -force ; wait ;
Mac users can now continue at step 4
Tip: For a full GPG walk through on the mac see this guide (not needed for our use-case)
https://notes.jerzygangi.com/the-best-pgp-tutorial-for-mac-os-x-ever/
The steps needed for our use-case are as follows:
1. Install GPG tools & pcscd (and other things like yubikey drivers stuff) using your favorite package manager, for example:
To do this via the CLI for OpenSC cards like Yubikeys:
sudo apt-get update ; wait ; sudo apt-get install gnupg2 pcscd opensc gpgsm gnupg-agent scdaemon pcsc-tools gnupg-pkcs11-scd libccid
Caveat: Test the Basics
To save some headache latter it is a good idea to check the card's answer to reset via the pc/sc libraries:
# With the card pluged in:
pcsc_scan
in the output you should see a line like:
Possibly identified card (using ~/.cache/smartcard_list.txt):
<The ATR in HEX>
Yubico Yubikey 4 OTP+U2F+CCID
if so continue at step 4, however If instead you ONLY see something like:
Possibly identified card (using /usr/share/pcsc/smartcard_list.txt):
NONE
Then your card has not been detected properly and is unlikely to work with this setup. It is probably wise to seek help from someone who knows what they are doing, best find your nearest benevolent smart-card expert.
EXPERTS ONLY
If you are the nearest benevolent smart-card expert start with building pcsclite from source (this is needed on Rasbian distros for example)
#for example latest version is pcsclite 1.8.17 (as of 2016-05-29 15:27)
# tip: cd /tmp
curl --url https://alioth.debian.org/frs/download.php/file/4173/pcsc-lite-1.8.17.tar.bz2 -o ./pcsc-lite-1.8.17.tar.bz2
cd ./pcsc-lite-1.8.17
./bootstrap
./configure
make
#
Next we need to install the software tools to talk to the Yubikey.
The steps needed for our use-case are as follows:
1. install Yubikey Personalization Tools, PIV Tools, & LIBCCID Standalone Installer for Mac OS X (and any other extras you want) from https://www.yubico.com/support/downloads/
2. use brew to install libassuan, gnu-pkcs11-scd, libgpg-error & pkcs11-helper
brew install libassuan gnu-pkcs11-scd libgpg-error pkcs11-helper
The steps needed for our use-case are as follows:
1. install the Yubikey personalization tools (and any other extras you want like the Yubikey PAM extensions perhaps)
2. install the Yubikey PIV tools
To do this via the CLI for Yubikey 4 (yes it does say 'ykneo' below but these work with Yubikey 4 too):
sudo apt-get install ykneomgr libykneomgr0 yubikey-personalization yubikey-personalization-*
sudo apt-get install yubico-piv-tool yubikey-piv-manager
Caveat: Reboot required
If all went well up to this point, reboot the system to ensure all the installed software is started up (Expert users reboot too: we need some startup scripts at lower run levels).
Most things in cryptography rely upon a particular but arbitrary lack of predictability usually just referred to as Entropy.
Smart cards are no different. (see: https://www.emsec.rub.de/media/crypto/veroeffentlichungen/2014/02/04/paper_yubikey_sca.pdf and https://www.yubico.com/2016/05/secure-hardware-vs-open-source/)
Ensure you have a solid source of cryptographically safe entropy (especially after reboots)
Caveat: The how to for Entropy is a topic for another time. (See EGD)
While these ciphers are not perfect (true perfection in security is rarely possible or even practical) they are a considerable improvement to the defaults (Expert users: your milage may vary)
AES256, AES192, AES, or better
Again while these hash checksums are not perfect (true perfection in security is rarely possible or even practical) they are a considerable improvement to the defaults (Expert users: your milage may vary again)
SHA3-512, other SHA-512 or better
Caveat: These are only a best practice recommendation, (Crypto experts: namely better than SHA1)
Here's how to harden GPG's configuration with those choices
1 Modify: ~/.gnupg/gpg.conf using the following code:
# ensure the config files are created (done automatically by gpg2 when first run)
gpg2 --list-keys ;
#prefer SHA512 instead of SHA1
if [[ ( -z $( grep -F "personal-digest-preferences SHA512" ~/.gnupg/gpg.conf ) ) ]] ; then
echo "personal-digest-preferences SHA512 SHA384 SHA256 SHA224" >> ~/.gnupg/gpg.conf ;
fi
if [[ ( -z $( grep -F "cert-digest-algo SHA512" ~/.gnupg/gpg.conf ) ) ]] ; then
echo "cert-digest-algo SHA512" >> ~/.gnupg/gpg.conf ;
echo "" >> ~/.gnupg/gpg.conf ;
fi
if [[ ( -z $( grep -x -F "default-preference-list SHA512" ~/.gnupg/gpg.conf ) ) ]] ; then
echo "default-preference-list SHA512 SHA384 SHA256 SHA224 AES256 AES192 AES BZIP2 ZLIB ZIP Uncompressed" >> ~/.gnupg/gpg.conf ;
echo "" >> ~/.gnupg/gpg.conf ;
fi
if [[ ( -z $( grep -x -F "use-agent" ~/.gnupg/gpg.conf ) ) ]] ; then
echo "use-agent" >> ~/.gnupg/gpg.conf ;
echo "" >> ~/.gnupg/gpg.conf ;
fi
2 Modify: ~/.gnupg/gpg-agent.conf using the following code:
if [[ ( -z $( grep -x -F "enable-ssh-support" ~/.gnupg/gpg-agent.conf ) ) ]] ; then
echo "enable-ssh-support" >> ~/.gnupg/gpg-agent.conf ;
echo "" >> ~/.gnupg/gpg-agent.conf ;
fi
if [[ ( -z $( grep -x -F "write-env-file" ~/.gnupg/gpg-agent.conf ) ) ]] ; then
echo "write-env-file" >> ~/.gnupg/gpg-agent.conf ;
echo "" >> ~/.gnupg/gpg-agent.conf ;
fi
Make GPG More Usable
To get smart cards to work well it is best to disable gnome-keyring gpg and ssh handling
echo "X-GNOME-Autostart-enabled=false" | sudo tee -a /etc/xdg/autostart/gnome-keyring-gpg.desktop
echo "X-GNOME-Autostart-enabled=false" | sudo tee -a /etc/xdg/autostart/gnome-keyring-ssh.desktop
General settings (pin entry)
----------------------------
Next we setup prompt for the Yubikey's pin.
Mac OS X (including El Capitan)
if [[ ( -z $( grep -F "pinentry-program " ~/.gnupg/gpg-agent.conf ) ) ]] ; then
echo "pinentry-program /usr/local/MacGPG2/libexec/pinentry-mac.app/Contents/MacOS/pinentry-mac" >> ~/.gnupg/gpg-agent.conf ;
echo "" >> ~/.gnupg/gpg-agent.conf ;
fi
if [[ ( -z $( grep -F "pinentry-program " ~/.gnupg/gpg-agent.conf ) ) ]] ; then
echo "pinentry-program "$(which pinentry) >> ~/.gnupg/gpg-agent.conf ;
echo "" >> ~/.gnupg/gpg-agent.conf ;
fi
Now when prompted for your card's PIN GPG will use the pin-entry program:
MAC:
Ubuntu:
Carefully modify your bashrc/bash-profile to include these lines:
# ensure that the gpg agent is working with bash env
if [[ ( -f "${HOME}/.gpg-agent-info" ) ]]; then
# load current GPG/SSH helper agents info
. "${HOME}/.gpg-agent-info" ;
# setup the GPG/SSH environment to use helper agents (i.e make sub-shells work too)
export GPG_AGENT_INFO ;
export SSH_AUTH_SOCK ;
export SSH_AGENT_PID ;
# setup the GPG PID to use the current agent (i.e make sub-shells work too)
export GPG_AGENT_PID=$(echo "${GPG_AGENT_INFO}" | cut -d : -f 2 ) ;
else
# close any stale helper agents
pkill -9 gpg-agent ;
pkill -9 ssh-agent ;
# Launch new helper agent
if [[ $( \uname -s ) == "Darwin" ]] ; then
eval $(/usr/local/MacGPG2/bin/gpg-agent --enable-ssh-support --daemon --write-env-file )
else
eval $(gpg-agent -s --enable-ssh-support --daemon --write-env-file )
fi
# if your implementation is missing --write-env-file, and does not create the .gpg-agent-info file uncomment the following
# echo "GPG_AGENT_INFO=${GPG_AGENT_INFO} ; export GPG_AGENT_INFO" > "${HOME}/.gpg-agent-info"
# echo "SSH_AUTH_SOCK=${SSH_AUTH_SOCK} ; export SSH_AUTH_SOCK" >> "${HOME}/.gpg-agent-info"
# echo "SSH_AGENT_PID=${SSH_AGENT_PID} ; export SSH_AGENT_PID" >> "${HOME}/.gpg-agent-info"
# echo "GPG_AGENT_PID=$(echo "${GPG_AGENT_INFO}" | cut -d : -f 2 ) ; export GPG_AGENT_PID" >> "${HOME}/.gpg-agent-info"
fi
export GPG_TTY=$(tty)
The above code fixes a rare but very annoying bug where you can be using the card for program XYZ and then suddenly when you try with program JKL the card does't show up or worse crashes.
Caveat: 2nd Reboot required
Now reboot the system to ensure all the changes take effect.
(sorry for the pun)
Now your Yubikey is ready to personalize with 'gpg2 --card-edit', and the fun begins:
user@localhost:~$ gpg2 --card-edit
Reader ...........: 1050:0407:X:0
Application ID ...: D2760001240102010006000000010000
Version ..........: 2.1
Manufacturer .....: Yubico
Serial number ....: 00000001
Name of cardholder: [not set]
Language prefs ...: [not set]
Sex ..............: unspecified
URL of public key : [not set]
Login data .......: [not set]
Signature PIN ....: 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]
gpg/card> admin
Admin commands are allowed
gpg/card> passwd
gpg: OpenPGP card no. D2760001240102010006000000010000 detected
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? 3
PIN changed.
1 - change PIN
2 - unblock PIN
3 - change Admin PIN
4 - set the Reset Code
Q - quit
Your selection? q
gpg/card> help
quit quit this menu
admin show admin commands
help show this help
list list all available data
name change card holder's name
url change URL to retrieve key
fetch fetch the key specified in the card URL
login change the login name
lang change the language preferences
sex change card holder's sex
cafpr change a CA fingerprint
forcesig toggle the signature force PIN flag
generate generate new keys
passwd menu to change or unblock the PIN
verify verify the PIN and list all data
unblock unblock the PIN using a Reset Code
factory-reset destroy all keys and data
gpg/card> list
Reader ...........: 1050:0407:X:0
Application ID ...: D2760001240102010006000000010000
Version ..........: 2.1
Manufacturer .....: Yubico
Serial number ....: 00000001
Name of cardholder: [not set]
Language prefs ...: [not set]
Sex ..............: unspecified
URL of public key : [not set]
Login data .......: [not set]
Signature PIN ....: 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]
gpg/card> help
quit quit this menu
admin show admin commands
help show this help
list list all available data
name change card holder's name
url change URL to retrieve key
fetch fetch the key specified in the card URL
login change the login name
lang change the language preferences
sex change card holder's sex
cafpr change a CA fingerprint
forcesig toggle the signature force PIN flag
generate generate new keys
passwd menu to change or unblock the PIN
verify verify the PIN and list all data
unblock unblock the PIN using a Reset Code
factory-reset destroy all keys and data
gpg/card> name
Cardholder's surname: Last
Cardholder's given name: First
gpg/card> list
Reader ...........: 1050:0407:X:0
Application ID ...: D2760001240102010006000000010000
Version ..........: 2.1
Manufacturer .....: Yubico
Serial number ....: 00000001
Name of cardholder: First Last
Language prefs ...: [not set]
Sex ..............: unspecified
URL of public key : [not set]
Login data .......: [not set]
Signature PIN ....: 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]
gpg/card> help
quit quit this menu
admin show admin commands
help show this help
list list all available data
name change card holder's name
url change URL to retrieve key
fetch fetch the key specified in the card URL
login change the login name
lang change the language preferences
sex change card holder's sex
cafpr change a CA fingerprint
forcesig toggle the signature force PIN flag
generate generate new keys
passwd menu to change or unblock the PIN
verify verify the PIN and list all data
unblock unblock the PIN using a Reset Code
factory-reset destroy all keys and data
gpg/card> lang
Language preferences: en
gpg/card> sex
Sex ((M)ale, (F)emale or space): M
gpg/card> generate
Make off-card backup of encryption key? (Y/n) n
What keysize do you want for the Signature key? (2048) 4096
The card will now be re-configured to generate a key of 4096 bits
Note: There is no guarantee that the card supports the requested size.
If the key generation does not succeed, please check the
documentation of your card to see what sizes are allowed.
What keysize do you want for the Encryption key? (2048) 4096
The card will now be re-configured to generate a key of 4096 bits
What keysize do you want for the Authentication key? (2048) 4096
The card will now be re-configured to generate a key of 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) 730
Key expires at Sun 01 Jul 2018 01:01:00 PM PDT
Is this correct? (y/N) y
GnuPG needs to construct a user ID to identify your key.
Real name: First Last
Email address: youremailhere@example.com
Comment:
You selected this USER-ID:
"First Last <youremailhere@example.com>"
Change (N)ame, (C)omment, (E)mail or (O)kay/(Q)uit? O
gpg: key ABCDE123 marked as ultimately trusted
gpg: directory '~/.gnupg/openpgp-revocs.d' created
gpg: revocation certificate stored as '~/.gnupg/openpgp-revocs.d/00000000000000000000000000000000ABCDE123.rev'
public and secret key created and signed.
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
gpg: next trustdb check due at 2018-07-01
gpg/card> list
Reader ...........: 1050:0407:X:0
Application ID ...: D2760001240102010006000000010000
Version ..........: 2.1
Manufacturer .....: Yubico
Serial number ....: 00000001
Name of cardholder: First Last
Language prefs ...: en
Sex ..............: unspecified
URL of public key : [not set]
Login data .......: [not set]
Signature PIN ....: forced
Key attributes ...: rsa4096 rsa4096 rsa4096
Max. PIN lengths .: 127 127 127
PIN retry counter : 3 0 3
Signature counter : 4
Signature key ....: 0000 0000 0000 0000 0000 0000 0000 0000 ABCD E123
created ....: 2016-07-01 01:01:00
Encryption key....: 0000 0000 0000 0000 0000 0000 0000 0000 ABCD E124
created ....: 2016-07-01 01:01:00
Authentication key: 0000 0000 0000 0000 0000 0000 0000 0000 ABCD E125
created ....: 2016-07-01 01:01:00
General key info..: pub rsa4096/ABCDE123 2016-07-01 First Last <youremailhere@example.com>
sec> rsa4096/ABCDE123 created: 2016-07-01 expires: 2018-07-01
card-no: 0006 00000001
ssb> rsa4096/ABCDE124 created: 2016-07-01 expires: 2018-07-01
card-no: 0006 00000001
ssb> rsa4096/ABCDE125 created: 2016-07-01 expires: 2018-07-01
card-no: 0006 00000001
gpg/card> quit
gpg --default-key ABCDE123
OPTIONAL: Git users can use the yubikey to sign code:
To configure this
git config --global user.signingkey <key_id>
The card is now ready for GPG
The steps needed for our use-case are as follows:
open System Preferences
navigate to keyboard->shortcuts->services
remove the hotkeys from all of the openPGP actions so not to use by mistake and enable the following:
OpenPGP: Encrypt Selection to New Window
OpenPGP: Decrypt Selection to New Window
OpenPGP: Sign Selection to New Window
(and any others you want)
now select some text and try to encrypt it
Now you can use GPG with ANY application or website that supports text. Just select, encrypt, Copy the result and paste.
Debian Linux (including Ubuntu)
sadly GPG on linux is topic on it's own and not covered here. ... yet?
man gpg
Linux users should checkout https://www.gnupg.org/related_software/frontends.html#sec-1-3
If you configured gpg-agent to handle ssh (which we did in the setup for this guide) then SSH is the same as using SSH identities
To test from the CLI if your key is loaded:
ssh-add -l
You should see the fingerprint of your card for example:
4096 SHA256:997890bc85c5796408ceb20b0ca75dabe6fe868136e cardno:000600000001 (RSA)
To export the public ssh key:
ssh-add -L | fgrep "cardno" > ~/.ssh/pkcs11_ssh_id.pub
Caveat: to configure the server you will need to have the ssh server admin enable pubkey authentication and add your public key (i.e. the file ~/.ssh/pkcs11_ssh_id.pub from the above command) to the ssh server's authorized keys file.
Now with your key plugged in just ssh in to the server as usual and the key should be used to authenticate you.
You can test by having the server admin disable password authentication completely (a topic on it's own)
[image] ?
EXPERTS ONLY (or blogs for another day?)
certs and piv/civ
use the yubikey-piv-manager to configure the PIV/CIV mode of your key
pkcs11 and x509 login
to set up firefox and thunderbird to use the certificates you need to load the libraries installed earlier and use like soft certs
OTP/FIDO or just a great guest password with yubikey
if you use chrome you should use UTF/FIDO now too: https://developers.yubico.com/U2F/