passage: pass + age with PKCS#11
passage is a password manager CLI and library. It uses age for encryption using hardwre tokens that support PKCS#11. It is an homage to pass but instead of PGP it uses PKCS#11 ECDH keys and age to secure passwords.
[!CAUTION]
passage is in early development stages and it has not been tested or audited for production use.
Quick Start
passage only works with tokens that contain a NIST P-256 key and support deriving keys using Diffie-Hellman key exchange.
# Initialize the store
passage init
# Generate a password
passage generate example.com
# Show password
passage example.com
Introduction
Passwords are still the most common approach to online authentication.
A password manager makes it easier to avoid using the same password across various services.
A common approach is to have the manager create strong passwords and secure them using a single (master) key.
This way you only need a single key to have access to all managed passwords.
An in-depth introduction can be found here.
passage is a password manager that was developed with three goals in mind:
- Security.
- Ease of use, sharing, and backing up passwords.
- Cross-platform CLI support.
It is (nearly) a drop-in replacement to pass CLI but another approach to security.
Structure
passage stores passwords in a directory called store, e.g., .passage-store under user/home directory.
Each password is an age encrypted file that can be decrypted using a cryptographic token, e.g., a smart card or a hardware security module.
Passwords can be structured in further subdirectoies.
When decrypted, a password file contains the password in the first line and may contain additional information in the following lines, for example:
WFb)aKyvDpP6^(mP
Username: passage
E-Mail: [email protected]
Beside passwords, two extra files are contained in the store:
.recipients: contains a line-separated list of public-keys used to encrypt passwords.
.config: a JSON file with passage configurations.
These are created when initializing passage using init subcommand.
Workflow
A initialize passage store and manage passwords:
passage init: initialized the store and creates configurations. It requires the crypto token to be connected.
passage generate NAME: creates a new password for NAME. If you want to define the password yourself, use pass insert NAME instead.
passage show: reveals content of password file.
Security
Password files are encrypted using age.
The content is ecnrypted using a hybrid public key cryptography (HPKE) scheme as described in RFC 9180:
"Hybrid" public key encryption (HPKE) schemes, specified here, take a different approach: "generate the symmetric key and its encapsulation with the public key." Specifically, encrypted messages convey an encryption key encapsulated with a public key scheme, along with one or more arbitrary-sized ciphertexts encrypted using that key.
A DH-Based KEM is used where the private key of recipient is stored on the hardware token and the non-interactive Diffie-Hellman exchange is performed over the PKCS#11.
Note that at the moment passage only supports NIST P-256 elliptic curves.
Implementation Roadmap
passage follows the footsteps of pass, so it is tried to provide a similar interface.
The following describes the implementation status of commands:
-
init: there is no equivalent to gpg-id flag here. pass uses gpg-agent to match IDs (e.g., E-Mail addresses), to PGP keys.
-
ls: done.
-
grep: WILL NOT IMPLEMENT -> see find.
-
find: accepts only a single regexp instead of multiple pass-names. Its alias, search is not implemented.
-
show: done.
-
insert: done.
-
edit: windows is not tested!
-
generate: implemented in part. --in-place and --clip are missing.
-
rm: done.
-
mv: done.
-
cp: done.
-
git: done.
- (decrypt): implemented in part.
--clip is missing.