I log in to a server via public key authentication and then mount a container (using e.g. LUKS/dm-crypt or truecrypt). At the moment, I have to enter the container password manually. Is there a way to secure that container using e.g. the ssh agent? Or if that is not possible directly, can I encrypt the container password (or probably better, keyfile) with the ssh public key and use ssh agent to decrypt it temporarily?
Ssh – How to decrypt an encrypted container via ssh without entering a passphrase while requiring some client authentication
dm-cryptlinuxlukssshtruecrypt
Related Solutions
I think your requirement is valid, but on the other hand it is also difficult, because you are mixing symmetric and asymmetric encryption. Please correct me if I'm wrong.
Reasoning:
- The passphrase for your private key is to protect your private key and nothing else.
- This leads to the following situation: You want to use your private key to encrypt something that only you can decrypt. Your private key isn't intended for that, your public key is there to do that. Whatever you encrypt with your private key can be decrypted by your public key (signing), that's certainly not what you want. (Whatever gets encrypted by your public key can only be decrypted by your private key.)
- So you need to use your public key to encrypt your data, but for that, you don't need your private key passphrase for that. Only if you want to decrypt it you would need your private key and the passphrase.
Conclusion: Basically you want to re-use your passphrase for symmetric encryption. The only program you would want to give your passphrase is ssh-agent and this program does not do encryption/decryption only with the passphrase. The passphrase is only there to unlock your private key and then forgotten.
Recommendation: Use openssl enc
or gpg -e --symmetric
with passphrase-protected keyfiles for encryption. If you need to share the information, you can use the public key infrastucture of both programs to create a PKI/Web of Trust.
With openssl, something like this:
$ openssl enc -aes-256-ctr -in my.pdf -out mydata.enc
and decryption something like
$ openssl enc -aes-256-ctr -d -in mydata.enc -out mydecrypted.pdf
Update: It is important to note that the above openssl commands do NOT prevent the data from being tampered with. A simple bit flip in the enc file will result in corrupted decrypted data as well. The above commands cannot detected this, you need to check this for instance with a good checksum like SHA-256. There are cryptographic ways to do this in an integrated way, this is called a HMAC (Hash-based Message Authentication Code).
I don't think something like this exists right out of the box, but it should be possible. I'll put together some references for you.
First there's /etc/crypttab - typically you specify a key file or password in the third slot, but some distros allow you to specify an option in the fourth field called keyscript
(debian and opensuse support this: http://linux.frank4dd.com/en/man5/crypttab.htm). This script (which must be in "/lib/cryptsetup/scripts" iirc) can use the third field (what would normally be just the keyfile or password) as an argument. The keyscript's job is to send the actual decryption key to stdout, which cryptsetup then uses as the luks key in the normal fashion.
Second is that you will likely need to write the keyscript. netkeyscript
(in github) is an example of a keyscript that listens on a UDP multicast socket for the password; here is another more detailed example of a custom key script, complete with an implementation in sh
: http://wejn.org/how-to-make-passwordless-cryptsetup.html. How you code the keyscript (which I'll just call multifactor
) I leave as an exercise to you ;)
Third is the secret splitting. you can use an open source tool called "ssss" (google for "ssss-split") to split the luks password in the manner you describe. let's say you split it into 3 pieces (a,b,c) and require any 2 of them. store "a" on the usb drive, "b" in a vault, and "c" you store with the computer (unencrypted partition), or whatever. Of course you don't want "c" to be exposed, so encrypt it with a scheme of your choice using a passphrase you can remember, and call that passphrase "c0
", and the encrypted "c
" on your disk is "c'
". Now your crypttab will look something like
root /dev/disk/<blah blah> /dev/<usb>:/path/to/a+$/dev/<blah>:/path/to/c' keyscript=multifactor
what you actually will have for the third field will of course depend on what your keyscript is willing to accept
Ideally the keyscript should be able to determine that it needs your input to decrypt one or more of the keys (e.g.: c'
-> c
in this case), but you can use the third field to specify that as desired. In my example above, I used a leading $
to indicate that.
I'm not sure if it's possible to make the keyscript prompt for input, possibly on stderr, since any output on stdout is taken as the luks password. It would be nice if there was a sensible fallback.
Anyway, good luck and happy hacking :)
Best Answer
I did something similar to this once with a remote encfs where I stored backups from my local PC. Maybe this will help. I was using Ubuntu with gnome-keyring at the time.
dbus_session.sh
keyring_helper.py
keyring.py
backup.sh
The initial setup is pretty simple, do a
mkfifo passwd
on your remote server andkeyring_helper.py set <name> <server> <protocol>
on your desktop. Once that's complete, your desktop should write your password from the keyring to the fifo where a remote truecrypt process will read it via stdin.