Skip to main content

Control access to secrets via symmetric encryption and decryption using FIDO2 authenticators.

Project description

FidoVault

GitHub Release GitHub Release Date - Published_At PyPI Version PyPI Downloads

GitHub issues GitHub closed issues GitHub commit activity

FidoVault is a tool to control access to secrets via symmetric encryption and decryption using FIDO2 authenticators. A FidoVault vault file contains a secret encrypted via one or more FIDO2 authenticators, such that the secret is inaccessible without at least one of the authenticators, but any single authenticator can decrypt the secret. A password can optionally be required for decryption in addition to an authenticator.

[!CAUTION] Most FIDO2 authenticators cannot be "backed up" or duplicated. If all the authenticators of a particular FidoVault are lost (or "reset"), then that FidoVault will become permanently inaccessible.

Additionally, when FIDO2 authenticators make a credential, they generate two random values, credRandomWithUV and credRandomWithoutUV, and associate them with the credential. In the context of an assertion, the former is used when "user verification" (most commonly via the entry of a PIN) is performed and the latter when it is not. Consequently, secrets encrypted by an authenticator when user verification is not performed will not be able to be decrypted by the same authenticator when user verification is performed (and vice versa). For more detailed discussion of this issue and its implications, see here.

Hardware

Any standard USB authenticator that supports the HMAC Secret Extension (which reportedly most do) should work with FidoVault. NFC and Bluetooth authenticators have not been tested, and PC/SC authenticators are not currently supported. Development and testing have primarily been done using a Yubico Security Key.

Dependencies and Installation

FidoVault is written in Python 3, and has the following dependencies:

  • cryptography (Debian package python3-cryptography) (for symmetric encryption and decryption of secrets)
  • [python-]fido2>=2.0.0 (Debian package python3-fido2) (for accessing FIDO2 authenticators)

[!NOTE] FidoVault has been updated to work with version 2.0 of [python-]fido2, and the current code will not work with earlier versions.

FidoVault should work on any platform on which Python 3 and the above dependencies can be installed, although running under Windows may require administrator privileges, since Windows apparently requires administrator privileges for certain FIDO APIs.

At least on Linux, if FidoVault's dependencies are installed and available (e.g., on Debian via apt install python3-fido2, which will pull in python3-cryptography as well), then the script can be run directly without installation as path/to/fidovault.py. It can also be installed from PyPI via pip / pipx, in which case it can be run simply as fidovault.

Usage

Display usage instructions:

$ fidovault -h
usage: fidovault.py [-h] [-v VAULT] [-k KEY] [-p PARAMETERS] [-g N] [-m] [-i | -a]

Create and manage FidoVaults - control access to secrets via symmetric encryption and decryption using FIDO2 authenticators

options:
  -h, --help            show this help message and exit
  -v, --vault VAULT     FidoVault filename
  -k, --key KEY         use (only) this key section of the FidoVault
  -p, --parameters PARAMETERS
                        Argon2id parameters (default: 't=1,p=4,m=2097152'), only used when initializing a FidoVault or adding a key section to one
  -g, --generate N      generate FidoVault secret utilizing at least N cryptographically random bits (only used if initializing a FidoVault, otherwise ignored)
  -m, --mlockall        lock all process memory into RAM (Linux only, and the memlock limit must be high enough to accommodate the memory used by Argon2id)
  -i, --init            initialize a FidoVault
  -a, --add             add a key section to a FidoVault

If neither '--init' nor '--add' are specified, the program will attempt to output the FidoVault's secret to STDOUT

Initialize a FidoVault:

$ fidovault -i -v <vaultname>
Enter secret: 
Confirm secret: 
Please connect the device you wish to add (and disconnect any others).
Press <enter> when ready ... 
Checking device at /dev/hidraw1 ...
Device supports the hmac-secret extension
Creating FIDO2 credential ... 
Enter PIN: 
Touch your authenticator now ...
FIDO2 credential created
Enter name for this key section: (default is 'Key 1')
Perform user verification when using this key section? (y/n - default is y) 
Combine password with FIDO2 hmac-secret when using this key section? (y/n - default is y) 
Getting hmac-secret ...
Touch your authenticator now ...
Enter password: 
Confirm password: 
Key section 'Key 1' successfully added
FidoVault '<vaultname>' initialized

Add an additional authenticator to an existing FidoVault (connect an already added authenticator before proceeding):

$ fidovault -a -v <vaultname>
Checking device at /dev/hidraw1 ...
Valid credential found on device
Trying to decode token using 'Key 1' key section ...
Getting hmac-secret ...
Enter PIN: 
Touch your authenticator now ...
Enter password: 
Token decryption succeeded
Please connect the device you wish to add (and disconnect any others).
Press <enter> when ready ... 
Checking device at /dev/hidraw1 ...
Device supports the hmac-secret extension
Creating FIDO2 credential ... 
Enter PIN: 
Touch your authenticator now ...
FIDO2 credential created
Enter name for this key section: (default is 'Key 2')
Perform user verification when using this key section? (y/n - default is y) 
Combine password with FIDO2 hmac-secret when using this key section? (y/n - default is y) 
Getting hmac-secret ...
Touch your authenticator now ...
Enter password: 
Confirm password: 
Key section 'Key 2' successfully added
Updated FidoVault '<vaultname>'

Output a FidoVault secret:

$ fidovault -v <vaultname>
Checking device at /dev/hidraw1 ...
Valid credential found on device
Trying to decode token using 'Key 1' key section ...
Getting hmac-secret ...
Enter PIN: 
Touch your authenticator now ...
Enter password: 
Token decryption succeeded
<secret>

Providing a FidoVault secret to another program

FidoVault is designed to be used in conjunction with other programs, by providing a secret to them. For programs that accept a secret on STDIN, simply pipe FidoVault's STDOUT to them (all FidoVault user interaction output is written to STDERR / /dev/tty, and so will be printed to the terminal and not redirected to the other program). E.g., to use a FidoVault secret for symmetric encryption and decryption of a file with GnuPG, run:

$ fidovault -v <vaultname> | gpg --passphrase-fd 0 --pinentry-mode loopback -c <filename>

and:

$ fidovault -v <vaultname> | gpg --passphrase-fd 0 --pinentry-mode loopback --output <filename> -d <filename.gpg>

To open a KeePassXC database with a FidoVault secret as password, run:

$ fidovault -v <vaultname> | keepassxc --pw-stdin /path/to/database.kdbx

(Unfortunately, this only works if KeePassXC is not currently running.)

For programs that expect a secret as an argument, FidoVault can pass a secret to them via xargs. E.g., to open a KeePassXC database with a FidoVault secret as password via D-Bus when KeePassXC is already running, run:

$ fidovault -v <vaultname> | xargs qdbus org.keepassxc.KeePassXC.MainWindow /keepassxc org.keepassxc.KeePassXC.MainWindow.openDatabase /path/to/database.kdbx

(On Debian Sid, replace qdbus with qdbus6.)

To pass the secret at a position other than the end of the command, use the -I replace-str argument of xargs. E.g., to open a KeePassXC database with a FidoVault secret as a password plus a keyfile that resides somewhere in the filesystem via D-Bus, run:

$ fidovault -v <vaultname> | xargs -I % qdbus org.keepassxc.KeePassXC.MainWindow /keepassxc org.keepassxc.KeePassXC.MainWindow.openDatabase /path/to/database.kdbx % /path/to/keyfile

[!CAUTION] Including a secret in a command's arguments is generally considered insecure, since the secret will be visible to anyone with access to the system process list. The above qdbus command is additionally insecure since it will place the secret on the D-Bus message bus, which also may be accessible to others.

Memory Security

On Linux, on startup FidoVault calls prctl(PR_SET_DUMPABLE, 0) to disable ptracing and core dumping. If the -m command line flag is given, then FidoVault will also call mlockall(MCL_FUTURE) to lock memory into RAM and disable paging. Memory locking is not done by default, since FidoVault uses the Argon2id algorithm for key derivation, and Argon2id is designed to use a considerable amount of memory, which will cause the program to crash with a memory allocation error when run under typical memlock limits (e.g., 8 MiB in Debian).

Key Derivation

FidoVault currently uses the Argon2id algorithm to derive an encryption key from a combination of a FIDO2 hmac-secret, an optional password, and a randomly chosen key derivation salt. (Earlier versions of the program used the PBKDF2HMAC algorithm; to access a key section created with PBKDF2HMAC, use version 0.1.0 of the program.) The Argon2id parameters of iterations, lanes, and memory cost can be specified via the -p parameter, e.g.:

  • -p 't=1,p=4,m=2097152': This is the "FIRST RECOMMENDED option" of RFC 9106. It requires 2 GiB of memory, and is currently the default if -p is not specified.
  • -p 't=3,p=4,m=65536: This is the "SECOND RECOMMENDED option" of the RFC, for situations where "much less memory is available."

See the RFC for more information on choosing parameters. (The KDF salt and tag lengths cannot be user-specified: the former is always 128 bits (16 bytes), and the latter is always 256 bits (32 bytes).)

Background

The original motivation of FidoVault was the desire to implement a standalone tool to open KeePassXC databases with FIDO2 authenticators, but the code quickly evolved into a more general purpose tool. FidoVault's basic architecture was inspired by the discussion here, as well as the design of LUKS plus its systemd-cryptenroll extension. Indeed, I seriously contemplated using LUKS + systemd-cryptenroll (possibly with loop devices) as a general purpose FIDO2-protected secret store, but since LUKS is designed around block devices and the device mapper, it cannot be easily used by non-root users.

Alternatives

Other projects similar to FidoVault:

  • tokenring: "TokenRing is a back-end for the Python keyring module, which uses a hard token to encrypt your collection of passwords as a large Fernet token, composed of individual password entries, each of which is separately encrypted as a smaller Fernet token of its own."
  • age-plugin-fido: "draft fido plugin for age(1)" ("early draft, likely buggy, protocol not finalized", "usability issues with multiple fido keys", "not actually tested with age(1) yet")
  • age-plugin-yubikey: "Encrypt files with fido2 keys that support the "hmac-secret" extension."
  • FileKey: "Files need protection. FileKey secures them. Works with Yubikeys. Drop files in. They lock. Drop them again. They unlock. Your data stays on your device, and only you hold the key. Open source and powered by AES-256 encryption—the same standard trusted by the US government for top-secret information." (Reddit announcement thread)
  • khefin: "A system for using a FIDO2 authenticator with hmac-secret extension support to generate passphrase-protected secrets." (abandoned a couple of years ago)

Contributors

Donations

FidoVault is absolutely free software, and there is no expectation of any sort of compensation or support for the project. That being said, if anyone wishes to donate (to Thomas More, the tool's primary author), this can be done via the Ko-fi platform.

License

FidoVault is free / open source software, released under the terms of the GNU GPLv3 or later.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

fidovault-0.2.0.tar.gz (29.1 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

fidovault-0.2.0-py2.py3-none-any.whl (25.3 kB view details)

Uploaded Python 2Python 3

File details

Details for the file fidovault-0.2.0.tar.gz.

File metadata

  • Download URL: fidovault-0.2.0.tar.gz
  • Upload date:
  • Size: 29.1 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: python-requests/2.32.5

File hashes

Hashes for fidovault-0.2.0.tar.gz
Algorithm Hash digest
SHA256 a96f28e5d7b7281e887d9c5dfb3829bcaa0bbcc032bb2314ab0fc637306135c3
MD5 03cc5570544c625e9fb6c83d6b787161
BLAKE2b-256 7b9f75d168d6349d46cab3d65b93588d43c80d90cecbf4775a446c5909f90d9b

See more details on using hashes here.

File details

Details for the file fidovault-0.2.0-py2.py3-none-any.whl.

File metadata

  • Download URL: fidovault-0.2.0-py2.py3-none-any.whl
  • Upload date:
  • Size: 25.3 kB
  • Tags: Python 2, Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: python-requests/2.32.5

File hashes

Hashes for fidovault-0.2.0-py2.py3-none-any.whl
Algorithm Hash digest
SHA256 ec0b9cdd387e3a2b87391d3aedf639b7bc28670cb7984458b6327a2c787a90c1
MD5 fa22d6b073add0bce01741213279660f
BLAKE2b-256 a22472b783676af57954f70a35d134de868abf0b3e412d69419f7a965946bb67

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page