Skip to content

Prerequisites for using derivepassphrase vault with an SSH key

Using derivepassphrase vault with an SSH key requires:

  1. a running SSH agent,
  2. a Python installation that can talk to the SSH agent, and
  3. a supported SSH key.

A running SSH agent

SSH agents are usually packaged as part of SSH client distributions. ssh-agent from OpenSSH and Pageant from PuTTY are known to work. gpg-agent (v2) from GnuPG is also known to work, but comes with caveats; see notes below.

If in doubt, we recommend OpenSSH because it is the de-facto canonical SSH agent implementation.

Agent-specific features

  • OpenSSH’s ssh-agent supports limiting the time the agent holds the key in memory (“key lifetime”). We recommend its usage.
  • ssh-agent and GnuPG’s gpg-agent support requiring confirmation upon each use for a specific key. We recommend its usage as well.

Other agent-specific notes

  • gpg-agent v2.0 and later uses a persistent database of known keys, SSH or otherwise. “Adding” a key to the agent actually means importing it, and requires choosing an “import passphrase” to protect the key on disk, in the persistent database. gpg-agent will cache the import passphrase in memory, and if that cache entry expires, then the import passphrase must be provided to unlock the key.

  • The GnuPG distribution does not contain tools to generate native SSH keys or interactively add keys to a running gpg-agent, because its purpose is to expose keys in a different format (OpenPGP) to other (agent-compatible) SSH clients. A third-party tool (such as a full SSH client distribution) is necessary to load/import native SSH keys into gpg-agent.

  • As a design consequence of the persistent database, gpg-agent always lists all known SSH keys as available in the agent. It is impossible to remove an SSH key from gpg-agent using standard SSH agent operations.

  • gpg-agent does not advertise its communication socket by default, contrary to other SSH agents, so it must be manually advertised:

    $ SSH_AUTH_SOCK="$(gpgconf --list-dirs agent-ssh-socket)"
    $ export SSH_AUTH_SOCK
    

A Python installation that can talk to the SSH agent

Windows is currently not supported

→ Further details: Issue the-13th-letter/derivepassphrase#13: Support PuTTY/Pageant on Windows

The two major SSH agents on Windows (PuTTY/Pageant and OpenSSH) use Windows named pipes for communication, and Python on Windows does not inherently support named pipes. Since no comprehensive third-party Python modules to interface with named pipes appear to exist, teaching derivepassphrase to use Windows named pipes will require us developers to write a custom low-level C module specific to this application—an unrealistic task if we lack both technical know-how for the named pipe API as well as Windows hardware to test any potential implementation on.

On non-Windows operating systems, the SSH agent is expected to advertise its communication socket via the SSH_AUTH_SOCK environment variable, which is common procedure. Therefore, your Python installation must support UNIX domain sockets.

A supported SSH key

For an SSH key to be usable by derivepassphrase, the SSH agent must always generate the same signature for the same input, i.e. the signature must be deterministic for this key type. Commonly used SSH key types include RSA, DSA, ECDSA, Ed25519 and Ed448.

  • RSA, Ed25519 and Ed448 signatures are deterministic by definition. Thus RSA, Ed25519 and Ed448 keys are supported under any SSH agent that implements them.

  • DSA and ECDSA signatures require choosing a value specific to each signature (a “cryptographic nonce”), which must be unpredictable. Typical DSA/ECDSA implementations therefore generate a suitably large random number as the nonce. This makes signatures non-deterministic, and thus unsuitable for derivepassphrase.

    Exception: PuTTY/Pageant and RFC 6979

    RFC 6979 specifies a method to calculate the nonce from the DSA/ECDSA key and the message to be signed. DSA/ECDSA signatures from SSH agents implementing RFC 6979 are therefore deterministic, and thus also suitable for derivepassphrase. Pageant 0.81 implements RFC 6979.

    Warning: Pageant < 0.81

    Pageant 0.80 and earlier uses a different, homegrown method to calculate the nonce deterministically. Those versions are also prinicipally suitable for use with derivepassphrase, but they generate different signatures – and different derived passphrases – than Pageant 0.81 and later.

What SSH key type do I have?

If, according to your SSH agent, your key’s type…

  • …ends with -cert-v01@openssh.com, then, for the purposes of this list, ignore the -cert-v01@openssh.com suffix.
  • …is dsa or ssh-dss, or is dsa followed by a number, then your key type is DSA.
  • …is rsa or ssh-rsa, or is rsa followed by a number, then your key type is RSA.
  • …is ecdsa followed by a number, or is ecdsa-sha2-nistp followed by a number, then your key type is ECDSA.
  • …is ssh-ed25519, then your key type is Ed25519.
  • …is ssh-ed448, then your key type is Ed448.

If you do not yet have a (supported) SSH key, we recommend Ed25519 for maximum speed and reasonable availability, otherwise RSA for maximum availability. We do not in general recommend Ed448 because it is not widely implemented.

Generating new SSH keys for derivepassphrase

The resulting key will be stored in ~/.ssh/my-vault-ed25519-key, using “vault key” as a comment. Replace -t ed25519 with -t rsa if generating an RSA key, and adapt the filename accordingly.

$ ssh-keygen -t ed25519 -f ~/.ssh/my-vault-ed25519-key -C "vault key"
Generating public/private ed25519 key pair.
Enter passphrase for ".../.ssh/my-vault-ed25519-key" (empty for no passphrase): 
Enter same passphrase again:
Your identification has been saved in .../.ssh/my-vault-ed25519-key
Your public key has been saved in .../.ssh/my-vault-ed25519-key.pub
The key fingerprint is:
SHA256:0h+WAokssfhzfzVyuMLJlIcWyCtk5WiXI8BHyhXYxC0 vault key
The key's randomart image is:
+--[ED25519 256]--+
|o B=+            |
|.=oE = .         |
|.oX @ +          |
| = + o * . .     |
|  + o * S B      |
|   + * + O o     |
|      * o .      |
|       o         |
|                 |
+----[SHA256]-----+

(The key fingerprint and the randomart image will naturally differ, as they are key-specific.)

The resulting key will be stored in ~/.ssh/my-vault-ed25519-key.ppk, using “vault key” as a comment. Replace -t ed25519 with -t rsa if generating an RSA key, and adapt the filename accordingly.

$ puttygen -t ed25519 -o ~/.ssh/my-vault-ed25519-key.ppk -C "vault key"
Enter passphrase to save key: 
Re-enter passphrase to verify: 

Not supported natively. An alternative SSH client distribution such as OpenSSH or PuTTY is necessary.

Alternatively, GnuPG supports reusing keys in its native OpenPGP format for SSH as long as the underlying key type is compatible.