Skip to content

lokori/secretman

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

26 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

secretman

Tools for managing secrets with Yubikey. This is a work-in-progress at the moment, but may become something like a tutorial or Proof-of-Concept. We'll see.

This is not a review of the product, just my notes about using it for practical purposes. I have identified several use-cases and tried to cover these case by case.

What is Yubikey

Yubikey is a commercial product which can be used to some interesting and useful things, such as: encrypting files, signing data digitally and as a two-factor authentication mechanism. Effectively Yubikey is a hardware implementation which controls access to the secret keys necessary for those feats and these secret keys can't be extracted. (At least, there are no known exploits or practical ways to extract the keys or make a copy of the key).

Yubikey is not unique, there are other similar products emerging, such as OnlyKey, which is essentially similar to Yubikey.

Being a programmer I want the solution to have three primary properties:

  1. Support command line access and automation as much as possible.
  2. There must be a way to recover if the Yubikey is lost or destroyed and one should test the recovery plan in advance to make sure it actually works.
  3. Should not require me to trust blackbox 3rd party products.

Arguably, Yubikey itself is a commercial closed source product, but I'm fine with that. Even if the product had some flaw in it's design, physical access to my Yubikey is a significant barrier against attacks.

Overview of the topics and possibilities:

Yubikey mindmap

Use-case 1: two-factor authentication, using FIDO U2F

The most common two-factor authentication is perhaps Google Authenticator used with a phone. SMS being perhaps the second most popular. RSA dongles work, but they cost money and can't be used for anything else so they are out for most normal use cases.

FIDO U2F is a new standard and super simple way for user to authenticate actions for a web application. This FIDO U2F tutorial explains how it works internally. The important thing is that a web browser (and web application) is allowed to talk with FIDO U2F compliant USB device without resorting to complicated things like WebUSB.

Compared to a phone, this is better from the security point of view. Yubikey supports other authentication mechanisms and can be used to emulate Google Authenticator, but FIDO U2F is usable for normal people without technical knowledge. The other use-cases I have considered are not so easy for users.

Technical preparations and precautions for advanced use

There are multiple tutorials about these things, here are some I used as a reference:

Here's a short summary. I use a Mac, so all steps are not appropriate for Linux or Windows, ability to reason required.

Install necessary software

  • Install GPG (OpenPGP). Make sure it's v2 to support 4096 bit keys.
  • Install pinentry program (with Mac at least)

(Assumed that you are using Homebrew, but you almost certainly are if you are a developer working with a Mac)

See Homebrew/homebrew-core#14737

brew install pinentry-mac
echo "pinentry-program /usr/local/bin/pinentry-mac" >> ~/.gnupg/gpg-agent.conf

Pinentry program is used by gpg to ask for your PIN code (in case of Yubikey) or a passphrase (in case of a local passphrase protected key). In my case it's a graphical prompt like this:

Insert card enter PIN

Invalid pinentry configuration will prevent Yubikey from working.

Note about the modes and ykpersonalize

Most tutorials suggest setting the mode of the Yubikey with ykpersonalize -m82. I suggest don't do that because Yubikeys sold after 2015 should ship with proper settings preconfigured. I either accidentally bricked my first Yubikey 4 or it had some production flaw, but it can't function as a smart card device. U2F works though.

Opening up NEO Manager you should see something like this:

NEO manager

CCID mode is required for accessing the smart card functionality on the Yubikey.

Apparently Yubikey Manager is a somewhat enchanced version of NEO Manager and replaces it. Confusing? Yes.

Generate keys

First, some reference material:

gpg --armor --export XX > XX_key.pub
gpg --armor --export-secret-key XX >> XX_key.priv

Put these into a safe place, not connected to anything or powered up. If (when) you lose your Yubikey, these are the only way to recover or create a new Yubikey with the same secret keys. Consider that you could lose these too in a catastrophe and USB sticks and other things deteoriate over time.

  • Move keys to the Yubikey "smart card"

Edit the main

gpg --edit-key XXXX

select keys one at a time, transfer keytocard and save

  • Make sure everything is ok
gpg --card-status
gpg --list-secret-keys

keylisting should show > for the moved keys. Something like this:

sec#  rsa4096 2016-08-23 [SC]
      3KOKOASKOKASDOKASDOKADS
uid           [ultimate] Antti Virtanen <antti.virtanen@solita.fi>
ssb#  rsa4096 2016-08-23 [E] [expires: 2020-08-23]
ssb>  rsa4096 2017-09-04 [E]
ssb>  rsa4096 2017-09-04 [S]
ssb>  rsa4096 2017-09-04 [A]
  • As explained in the referenced tutorial, it is reasonable to remove the ultimate master key from the system to prevent anyone from creating more subkeys.
  • After this the subkeys are "untrusted" and gpg will ask for confirmation. Make it trustworthy again to get rid of this:
gpg --edit-key XXXXX
trust

Setting touch mode for the keys

By default, Yubikey does not require touch triggering for the keys, while it may require a PIN code. It appears that setting the touch mode for the keys can't be done using the normal Yubico provided management tools, but it's possible to set this through more direct means.

yubitouch.sh is a script which talks directly to the Yubikey and allows setting touch feature for the keys.

It is a matter of opinion if this is a good thing, but certainly it adds some security as Mallory can't piggybag with your PIN entry when you enter the pin. On the other hand, it may be annoying to press the button every time.

Especially decrypt may benefit from the touch requirement. It essentially prevents Mallory from decrypting all your secrets if he captures the PIN when you enter it.

./yubitouch.sh dec on
All done!

Set Yubi PIN codes

Set admin PIN and normal user PIN. Try not to forget these or you will be totally locked out.

Use-case 2: File encryption

File encryption is based on the smart card properties of the card. This means user needs to install enough software to talk to smart cards and there are several alternatives to doing this. See Yubico articles on OpenPGP.

Being a programmer I want an easy solution. There are two scripts in this repository: poke.sh and peek.sh.

Basically these are wrappers to call opengpg to encrypt and decrypt stuff identified by a key, which is also the name of the file written by the script. If you use the scripts, change the directory for storing the secrets if necessary. This is a very crude "password manager" at the moment. Also, you should change the key identifier to match the key identifier of your encryption key if you decide to use these scripts.

Call gpg for encryption (XXXX being your key id):

gpg --encrypt --armor --recipient XXXXX > secret.txt

And decrypt: cat secret.txt | gpg --decrypt

Poke/peek scripts

  • ask confirmation for overwriting existing key
  • can read data from stdin or command line argument
  • you could use / or other special characters for key and cause problems. Use common sense.

Example:

./poke.sh kak < kungfury.txt
Securing data with vault key kak.
Key exists, overwrite?  [y/N] y
overwriting
Data from standard input.
./peek.sh kak
Decrypting secret data with vault key kak
gpg: encrypted with 4096-bit RSA key, ID D2E72CF23AD1899D, created 2017-09-04
      "Antti Virtanen <antti.virtanen@solita.fi>"
secret two finger death punch

NOTE: your secrets may get recorded in the command shell history. Do not leave them there.

Handy tweaks for poke/peek

cat ~/.bash_profile
alias smanpoke=~/projects/secretman/poke.sh
alias smanpeek=~/projects/secretman/peek.sh
alias smanls="ls ~/.secretman/"

In my case ~/.secretman is actually a symbolic link to another folder, which gets automatically copied to cloud. So the encrypted data is automatically backed up, but even if the cloud service is compromised, my secrets can't be stolen by the attacker. Not perfect, but good enough for my needs.

UPDATE: I learnt recently that a project called pass is essentially similar, but slightly more sophisticated, version of my scripts. The implementation has the same core idea of using filesystem to store the passwords encrypted.

Making sure it can be decrypted even without the Yubikey in an emergency:

BE VERY CAREFUL.

  • killall gpg-agent
  • Remove .gnupg directory (move to another name)
  • import the backup keys (gpg --import)
  • try to decrypt
  • might need to configure pinentry for gpg-agent

If everything is ok, kill gpg-agent again and restore the normal .gnupg

Threat scenarios

The intention of poke and peek scripts is that each "secret" or "password" is separately encrypted/decrypted, instead of having one master password and a single database (or text file) to hold all secrets. The latter approach allows attacker to gain access to all secrets immediately when the local machine decrypts them using the smart card, while this approach only allows access to the secrets decrypted recently.

This is free and does not depend on any particular software vendor for security or to actually work. A self-made "password manager", although admittedly quick&dirty.

Use-case 3: Secure SSH authentication

See:

Secret key only suitable for authentication is on your Yubikey (per the preparations earlier). Public key is on your local machine.

  • Make it suitable for SSH:
gpg --export-ssh-key XXXX > a_solita_ssh.pub
  • Put the public key to remote server, ~/.ssh/authorized_keys. Proper chmod.
  • Config public key authentication for sshd, /etc/sshd/sshd.conf. Restard sshd.
  • Get the key grip: gpg -k --with-keygrip
  • Configure gpg-agent

Example:

killall gpg-agent
echo '1XOKASODKOASKDAOSKDAOKASD' > ~/.gnupg/sshcontrol 
echo 'enable-ssh-support' >> ~/.gnupg/gpg-agent.conf
export SSH_AUTH_SOCK=$(gpgconf --list-dirs agent-ssh-socket)
gpgconf --launch gpg-agent

If everything is ok you should see the key now with

ssh-add -l

To sign on to server use ssh -v to see how the key works (or doesn't work).

  • If you can authenticate using the key you can disable password authentication if appropriate.
  • Configure your login script to export SSH_AUTH_SOCK so you don't have to do it again in the future.
  • Before removing password login, make sure you can actually authenticate by importing your key for a fresh .gnupg configuration without the Yubikey. Similar to encryption backup test.

Threat scenarios

If everything is ok, now your authentication to a remote server should not depend on a secret key on your local machine. The ssh-agent forwards the authentication challenge to your Yubikey which doesn't reveal your secret key. Effectively this means that a malicious attacker can only compromise a connection you have open, which mitigates the risk significantly.

Use-case 4: AWS multi-factor authentication

Update 2.10. 2018: AWS has now added support for Yubikey in the web console. See AWS instructions for management console for how to set it up.

Amazon doesn't support FIDO U2F or Yubikey for AWS CLI client at the moment. This likely to change. I'm assuming you have already created users in AWS and installed CLI tools.

Console with Yubikey Authenticator

  • Download Yubikey Authenticator to emulate Google Authenticator TOTP protocol.
  • Enable MFA from AWS console for the user.
  • Setup a backup device (offline) or save the Authenticator seed (QR-code) in a safe offline storage. Otherwise you may get locked out of your account after Yubikey is lost or destroyed one day. BE VERY CAREFUL HERE
  • Scan QR code for Authenticator (Authenticator captures it from the computer's screen).

Authenticator setup

  • Enable password protection if you want more than a physical presence of Yubikey to secure the code.

After this, the user can only log in to the AWS console if the Yubikey is physically present on the machine.

AWS CLI interface

  • Create secret key for cli access
  • update ~/.aws/config appropriately
  • Test that everything works without MFA:
aws sts get-caller-identity --profile mfa-testi
{
    "Account": "6666125989891285952", 
    "UserId": "AIDAJBGASLKLK7Rq2C5U", 
    "Arn": "arn:aws:iam::6666512345252:user/mfa-testi"
}
  • Install ykman and other tools from Yubikey Manager

  • Create test user

  • Attach the Virtual MFA Device to access key use with policy. Like this:

{
  "Version": "2012-10-17",
  "Statement": [{
    "Effect": "Allow",
    "Action": [
      "ec2:*",
      "s3:*"
    ],
    "Resource": ["*"],
    "Condition": {"Bool": {"aws:MultiFactorAuthPresent": "true"}}
  }]
}
  • Test that your policy can't access the resources:
aws s3 ls --profile mfa-testi

A client error (AccessDenied) occurred when calling the ListBuckets operation: Access Denied
  • To use CLI, get temporary session token first. Like this:
 aws sts get-session-token --serial-number arn:aws:iam::6666666652:mfa/mfa-testi --token-code 310353 --profile mfa-testi
  • export credentials for CLI:
export AWS_ACCESS_KEY_ID=kk
export AWS_SECRET_ACCESS_KEY=kk
export AWS_SESSION_TOKEN=kk
  • Test that you can now access the resources having authenticated using the session token
aws s3 ls
  • This procedure can be scripted. I used woowa's script and fixed a few things. See awsenv.sh as a reference for automated session token + authentication.

  • you could alternatively use something like mfa_serial = arn:aws:iam::1313413414313:mfa/ on ~/.aws/config and the CLI then prompts for manually inputting the MFA code.

More material about AWS and Yubikey MFA:

Threat scenarios

Simply getting secret access key from ~/.aws/config no longer allows direct access to AWS CLI resources. The authenticator codes can be accessed by the attacker when Yubikey is attached to your computer, but temporary session token from AWS has time-to-live. Basically the attacker must risk detection as you are present on your computer if the attacker wants to do actions with your session token.

Not perfect, but an order of magnitude better than compromising access if the local files can be read by the attacker.

Use-case 5: Signing data and files

TODO

Use-case 6: two-factor authentication, without FIDO U2F

TODO

Releases

No releases published

Packages

No packages published

Languages