---
title: What are "interchangable passphrases" in `vault`, and what does that mean in practice?
---
# What are "interchangable passphrases" in `vault`, and what does that mean in practice?
## What are "interchangable passphrases"?
The "vault" derivation scheme internally uses PBKDF2-HMAC-SHA1[^1] to turn
the master passphrase[^2] into a pseudo-random bit sequence, which then
drives the actual passphrase derivation.
In this context, the master passphrase is passed directly as a key to
HMAC-SHA1, and because HMAC-SHA1 requires keys of exactly 64 bytes size, the
key is thus subject to the HMAC key mapping procedure.
Because the mapping of infinitely many arbitrarily sized keys to 64-byte
sized keys cannot be one-to-one, there exist pairs of keys that behave
identically when passed into (PBKDF2-)HMAC-SHA1, i.e., the keys (master
passphrases) are "interchangable" from the vault scheme's perspective.
Fundamentally, this is an issue of *encoding*: the master passphrase is
interpreted as an encoding of the HMAC-SHA1 key, and this encoding is not
unique, so the effective space of HMAC-SHA1 keys is reduced through the
presence of "non-canonical" encodings of keys.
[^1]: PBKDF2 is a key derivation function, published in [RFC 2898][].
It uses a pseudo-random function such as HMAC-SHA1 (hashed message
authentication code, specified in [RFC 2104][] and using SHA1 as the
underlying hash function) when processing its input. PBKDF2 passes the
key on to its pseudo-random function, and otherwise only depends on the
output of the pseudo-random function, not on the key.
[^2]: If you use a master SSH key, it is first converted to an "equivalent
master passphrase".
[RFC 2104]: https://datatracker.ietf.org/doc/html/rfc2104
[RFC 2898]: https://datatracker.ietf.org/doc/html/rfc2898
## What is the HMAC key mapping procedure?
???+ abstract "HMAC key mapping procedure"
Let <var>MP</var> denote the master passphrase, and let <var>K</var>
denote the HMAC key candidate. Let <var>B</var> denote the block size
of HMAC-SHA1 in bytes, i.e., `64`. At the beginning,
<var>K</var>·=·<var>MP</var>.
1. If <var>K</var> (=·<var>MP</var>) is larger than <var>B</var>, set
<var>K</var> to `SHA1(K)`. This updates <var>K</var> for all
further steps below.
2. If <var>K</var> is smaller than <var>B</var>, append as many NUL
bytes as necessary to extend <var>K</var> to size <var>B</var>.