• Stars
    star
    590
  • Rank 75,794 (Top 2 %)
  • Language
    Rust
  • License
    Apache License 2.0
  • Created about 4 years ago
  • Updated 27 days ago

Reviews

There are no reviews yet. Be the first to send feedback to the community and the maintainers!

Repository Details

YubiKey plugin for age

YubiKey plugin for age clients

age-plugin-yubikey is a plugin for age clients like age and rage, which enables files to be encrypted to age identities stored on YubiKeys.

Installation

Environment CLI command
Cargo (Rust 1.65+) cargo install age-plugin-yubikey
Homebrew (macOS or Linux) brew install age-plugin-yubikey

On Windows, Linux, and macOS, you can use the pre-built binaries.

Help from new packagers is very welcome.

Linux, BSD, etc.

On non-Windows, non-macOS systems, you need to ensure that the pcscd service is installed and running.

Environment CLI command
Debian or Ubuntu sudo apt-get install pcscd
OpenBSD As root do:
pkg_add pcsc-lite ccid
rcctl enable pcscd
rcctl start pcscd
FreeBSD As root do:
pkg install pcsc-lite libccid
service pcscd enable
service pcscd start

When installing via Cargo, you also need to ensure that the development headers for the pcsc-lite library are available, so that the pcsc-sys crate can be compiled.

Environment CLI command
Debian or Ubuntu sudo apt-get install libpcsclite-dev

Windows Subsystem for Linux (WSL)

WSL does not currently provide native support for USB devices. However, Windows binaries installed on the host can be run from inside a WSL environment. This means that you can encrypt or decrypt files inside a WSL environment with a YubiKey:

  1. Install age-plugin-yubikey on the Windows host.
  2. Install an age client inside the WSL environment.
  3. Ensure that age-plugin-yubikey.exe is available in the WSL environment's PATH. For default WSL setups, the Windows host's PATH is automatically added to the WSL environment's PATH (see this Microsoft blog post for more details).

Configuration

age-plugin-yubikey identities have two parts:

  • The secret key material, which is stored inside a YubiKey.
  • An age identity file, which contains information that an age client can use to figure out which YubiKey secret key should be used.

There are two ways to configure a YubiKey as an age identity. You can run the plugin binary directly to use a simple text interface, which will create an age identity file:

$ age-plugin-yubikey

Or you can use command-line flags to programmatically generate an identity and print it to standard output:

$ age-plugin-yubikey --generate \
    [--serial SERIAL] \
    [--slot SLOT] \
    [--name NAME] \
    [--pin-policy PIN-POLICY] \
    [--touch-policy TOUCH-POLICY]

Once an identity has been created, you can regenerate it later:

$ age-plugin-yubikey --identity [--serial SERIAL] --slot SLOT

To use the identity with an age client, it needs to be stored in a file. When using the above programmatic flags, you can do this by redirecting standard output to a file. On a Unix system like macOS or Ubuntu:

$ age-plugin-yubikey --identity --slot SLOT > yubikey-identity.txt

Usage

The age recipients contained in all connected YubiKeys can be printed on standard output:

$ age-plugin-yubikey --list

To encrypt files to these YubiKey recipients, ensure that age-plugin-yubikey is accessible in your PATH, and then use the recipients with an age client as normal (e.g. rage -r age1yubikey1...).

The output of the --list command can also be used directly to encrypt files to all recipients (e.g. age -R filename.txt).

To decrypt files encrypted to a YubiKey identity, pass the identity file to the age client as normal (e.g. rage -d -i yubikey-identity.txt).

Advanced topics

Agent support

age-plugin-yubikey does not provide or interact with an agent for decryption. It does however attempt to preserve the PIN cache by not soft-resetting the YubiKey after a decryption or read-only operation, which enables YubiKey identities configured with a PIN policy of once to not prompt for the PIN on every decryption. This does not work for YubiKey 4 series.

The session that corresponds to the once policy can be ended in several ways, not all of which are necessarily intuitive:

  • Unplugging the YubiKey (the obvious way).
  • Using a different applet (e.g. FIDO2). This causes the PIV applet to be closed which clears its state.
    • This is why the YubiKey 4 series does not support PIN cache preservation: their serial can only be obtained by switching to the OTP applet.
  • Generating a new age identity via age-plugin-yubikey --generate or the CLI interface. This is to avoid leaving the YubiKey authenticated with the management key.

If the current PIN UX proves to be insufficient, a decryption agent will most likely be implemented as a separate age plugin that interacts with yubikey-agent, enabling YubiKeys to be used simultaneously with age and SSH.

Manual setup and technical details

age-plugin-yubikey only officially supports the following YubiKey variants, set up either via the text interface or the --generate flag:

  • YubiKey 4 series
  • YubiKey 5 series

NOTE: Nano and USB-C variants of the above are also supported. The pre-YK4 YubiKey NEO series is NOT supported. The blue "Security Key by Yubico" will also not work (as it doesn't support PIV).

In practice, any PIV token with an ECDSA P-256 key and certificate in one of the 20 "retired" slots should work. You can list all age-compatible keys with:

$ age-plugin-yubikey --list-all

age-plugin-yubikey implements several automatic security management features:

  • If it detects that the default PIN is being used, it will prompt the user to change the PIN. The PUK is then set to the same value as the PIN.
  • If it detects that the default management key is being used, it generates a random management key and stores it in PIN-protected metadata. age-plugin-yubikey does not support custom management keys.

License

Licensed under either of

at your option.

Contribution

Unless you explicitly state otherwise, any contribution intentionally submitted for inclusion in the work by you, as defined in the Apache-2.0 license, shall be dual licensed as above, without any additional terms or conditions.

More Repositories

1

rage

A simple, secure and modern file encryption tool (and Rust library) with small explicit keys, no config options, and UNIX-style composability.
Rust
2,594
star
2

ed25519-java

Pure Java implementation of EdDSA
Java
211
star
3

ire

I2P router implementation in Rust
Rust
150
star
4

zcash-pow

The proof-of-work algorithm for Zcash
Python
80
star
5

wage

A WASM package and web app for encrypting and decrypting age-encrypted files, powered by rage.
Vue
75
star
6

bls

Rust crate for BLS signatures
Rust
30
star
7

fpe

Format-preserving encryption in Rust
Rust
25
star
8

pinentry-rs

Rust interface for pinentry binaries
Rust
24
star
9

memuse

Traits for inspecting memory usage of Rust types
Rust
24
star
10

txi2p

I2P bindings for Twisted.
Python
12
star
11

backflip

Help your Flipper Zero perform tricks!
Rust
10
star
12

addchain

Rust crate for generating addition chains
Rust
8
star
13

zcon1-demo-wasm

JavaScript
7
star
14

age-plugin-remote

[UNFINISHED] Expose local age identities to remote machines via SSH
Rust
6
star
15

partysig

Create and verify distributed multi-party signatures
Python
6
star
16

x509.rs

Pure-Rust X.509 serialization
Rust
5
star
17

girage

[ALPHA STATE] Graphical interface for a simple, secure, and modern encryption tool.
Rust
4
star
18

zk

Rust
4
star
19

halo2-website

Rust
4
star
20

hazmat

A collection of helpers for working with hazardous materials in Rust crates.
Rust
2
star
21

i2p_elgamal

Rust implementation of I2P's 2048-bit ElGamal primitive
Rust
2
star
22

plc

Key management for DID PLC identities
Rust
2
star
23

mostly-harmless

A bag of various unrelated projects with varying levels of serviceability and destructiveness.
Rust
1
star
24

vrf-r255

Implementation of draft-irtf-cfrg-vrf-15 with ristretto255
Rust
1
star