You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
I'd like to propose/request an alternative to typing in passphrases that uses a mechanism many security-conscious users are likely familiar with: the SSH authentication agent.
SSH allows users who hold a private key to authenticate to remote SSH servers that have the corresponding public key. The authentication process involves the SSH server sending a random message to the client, which the client signs (with the user's private key), and then sends back to the server. The server can then verify that the signature corresponds to the public key, and if so, it lets the user in.
Ssh-agent facilitates this process, and uses a simple wire protocol to support it. One of the commands in this protocol is SSH_AGENTC_SIGN_REQUEST, which covers the server requesting a signature from the client of some arbitrary blob of data. Any program that speaks the ssh-agent protocol, usually via the Unix socket at $SSH_AUTH_SOCK, can make such a request.
Now, fscrypt is not using public-key cryptography in any way, just symmetric encryption which (for the protectors) usually takes the form of arbitrary passphrases. But I think that the ssh-agent signing functionality can be (ab)used as a convenient source for a secure "passphrase" that need not be typed in.
If you request a signature multiple times on an unchanging hunk of input data, you will get back the same signature every time. Even if the input data is publicly known, the signature (for a given public key) can only be generated by the user who holds the corresponding private key. So the signature, which can be requested automatically via ssh-agent, could in itself be used as a passphrase for an fscrypt protector. I believe it would be no worse, security-wise, than a (decent) typed-in custom passphrase.
I am attaching a rough proof-of-concept implementation of this idea, written in Python (not a Gopher, sorry) and using the Paramiko library. This script supports two operations:
$ ./fscrypt-ssh.py setup
will connect to a running ssh-agent, allow you to select a key (if there are multiple), and generate a passphrase that is derived from a signature (made using that key) of some arbitrary text. This passphrase should be used in a custom-passphrase protector for a test directory. This directory, in locked form, is then passed to the second operation:
$ ./fscrypt-ssh.py unlock DIRECTORY
This will connect to a running ssh-agent, and attempt to unlock DIRECTORY using the available keys.
Now, of course there are multiple devils in the details:
I'm not sure what should be used for the input data to be signed. It needs to be something that doesn't change for a given encrypted directory, or else the signature operation will return different results. And it probably can't be considered a secret. But using a hard-coded string that is always the same everywhere would probably not be good (if the signature-derived passphrase is compromised in one place, then it can be re-used wherever else the same private key is employed). Something incorporating the protector and/or policy ID, perhaps?
The proof-of-concept tries to unlock a directory using all the available keys, but this is dumb---it can already get the corresponding (public key) fingerprints from ssh-agent, so it should look for a key with a specific fingerprint. This information can't be stored in the existing protector types, however (unless you stuff it into a protector description, which appears to be read-only once created).
(Implementation note: Ssh-agent actually gives you the public keys in full, not just the fingerprints---the PoC generates SHA256 fingerprints itself, hashing and all. You can match against the entirety of the public key if desired, though that's probably overkill.)
The signature response from ssh-agent contains a variable-length header that should probably be chopped off before deriving a passphrase from it, as the header is obviously not high-entropy data. This article describes it.
By default, a user's ssh-agent is only accessible on the system where it is running. In order for the agent to be accessible on remote systems, agent forwarding needs to be enabled. This is not without risk. I don't think this is a significant issue for the usage proposed here---if an attacker can get access to a user's remote ssh-agent, then they could probably capture the keystrokes of a typed passphrase, too---but it is worth the disclaimer.
I am not a cryptographer, so running all this by one is probably advisable :-)
We have a good solution already for passphrase-less login access to remote systems, and I think the above approach can provide us similarly streamlined unlocking of local and remote encrypted directories.
The text was updated successfully, but these errors were encountered:
I'd like to propose/request an alternative to typing in passphrases that uses a mechanism many security-conscious users are likely familiar with: the SSH authentication agent.
SSH allows users who hold a private key to authenticate to remote SSH servers that have the corresponding public key. The authentication process involves the SSH server sending a random message to the client, which the client signs (with the user's private key), and then sends back to the server. The server can then verify that the signature corresponds to the public key, and if so, it lets the user in.
Ssh-agent facilitates this process, and uses a simple wire protocol to support it. One of the commands in this protocol is
SSH_AGENTC_SIGN_REQUEST
, which covers the server requesting a signature from the client of some arbitrary blob of data. Any program that speaks the ssh-agent protocol, usually via the Unix socket at$SSH_AUTH_SOCK
, can make such a request.Now, fscrypt is not using public-key cryptography in any way, just symmetric encryption which (for the protectors) usually takes the form of arbitrary passphrases. But I think that the ssh-agent signing functionality can be (ab)used as a convenient source for a secure "passphrase" that need not be typed in.
If you request a signature multiple times on an unchanging hunk of input data, you will get back the same signature every time. Even if the input data is publicly known, the signature (for a given public key) can only be generated by the user who holds the corresponding private key. So the signature, which can be requested automatically via ssh-agent, could in itself be used as a passphrase for an fscrypt protector. I believe it would be no worse, security-wise, than a (decent) typed-in custom passphrase.
I am attaching a rough proof-of-concept implementation of this idea, written in Python (not a Gopher, sorry) and using the Paramiko library. This script supports two operations:
will connect to a running ssh-agent, allow you to select a key (if there are multiple), and generate a passphrase that is derived from a signature (made using that key) of some arbitrary text. This passphrase should be used in a custom-passphrase protector for a test directory. This directory, in locked form, is then passed to the second operation:
This will connect to a running ssh-agent, and attempt to unlock
DIRECTORY
using the available keys.Now, of course there are multiple devils in the details:
I'm not sure what should be used for the input data to be signed. It needs to be something that doesn't change for a given encrypted directory, or else the signature operation will return different results. And it probably can't be considered a secret. But using a hard-coded string that is always the same everywhere would probably not be good (if the signature-derived passphrase is compromised in one place, then it can be re-used wherever else the same private key is employed). Something incorporating the protector and/or policy ID, perhaps?
The proof-of-concept tries to unlock a directory using all the available keys, but this is dumb---it can already get the corresponding (public key) fingerprints from ssh-agent, so it should look for a key with a specific fingerprint. This information can't be stored in the existing protector types, however (unless you stuff it into a protector description, which appears to be read-only once created).
(Implementation note: Ssh-agent actually gives you the public keys in full, not just the fingerprints---the PoC generates SHA256 fingerprints itself, hashing and all. You can match against the entirety of the public key if desired, though that's probably overkill.)
The signature response from ssh-agent contains a variable-length header that should probably be chopped off before deriving a passphrase from it, as the header is obviously not high-entropy data. This article describes it.
By default, a user's ssh-agent is only accessible on the system where it is running. In order for the agent to be accessible on remote systems, agent forwarding needs to be enabled. This is not without risk. I don't think this is a significant issue for the usage proposed here---if an attacker can get access to a user's remote ssh-agent, then they could probably capture the keystrokes of a typed passphrase, too---but it is worth the disclaimer.
I am not a cryptographer, so running all this by one is probably advisable :-)
We have a good solution already for passphrase-less login access to remote systems, and I think the above approach can provide us similarly streamlined unlocking of local and remote encrypted directories.
The text was updated successfully, but these errors were encountered: