8

There's an encrypted filesystem on a server I ssh into using public key authentication. Since a forwarded ssh-agent can deterministically sign a message (see also the ssh-agent protocol section 2.6.2), I consider using a message stored on the server combined1 with its signature (using a private RSA key stored on the client via the forwarded ssh-agent) as password piped to the encryption program to solve my question How to decrypt an encrypted container via ssh without entering a passphrase while requiring some client authentication? (but basically any password prompting application could be involved here) and then discarded again. But is this a good (=secure) idea? What kind of combination between message and signature should I actually use? Is there a need for using a different key pair than for the ssh authentication? Or am I trying to invent a triangular wheel?

1 Does combining the original message with the signature actually help in any way compared to simply using the signature alone? (Apart from entropy, but assume key stretching is applied anyway)

Here's a short summary of how SSHv2 public key authentication works:
sshd on the remote server expects the client's ssh or ssh-agent to sign a predetermined message with its private key (that is not stored remotely) and the server can then verify it via the forwarded public key and check it against the user's authorized_keys database.
ssh-agent-forwarding now usually consists of connecting to a third PC. The intermediate PC generates the message, but asks the original client's ssh-agent to sign it, without ever getting to know the private key itself. This very same signature instruction is what I want to use to obtain a "secret" (the signature, not the public key) that can be used as a password that is not stored anywhere (and cannot be reproduced on the client alone if the message-to-be-signed is stored only on the server) - no third PC involved, only the agent forwarding.

Here's an illustration of the process I intend to implement:

Client:                   Server:
>ssh-add SECRET RSA KEY
>ssh -A server            <-- connect, forward agent (authentication does not
                                         need to use that specific secret key)

                          Connect to the `SSH_AUTH_SOCK` unix socket and ask
                          the client's ssh-agent to sign MESSAGE with SECRET RSA KEY
                          (knowing only the respective PUBLIC RSA KEY to identify it)
ssh-agent signs MESSAGE --> SIGNATURE
                          [optionally verify SIGNATURE]

                          Use SIGNATURE as PASSWORD,
                          pipe that to the program and forget it.

To my understanding this implies the following:
Should the server be stolen, the thief would have to intercept the client signing MESSAGE, otherwise they can't obtain PASSWORD. Should the client be stolen, without MESSAGE not even SIGNATURE can be generated. Thus both server and client need to be stolen and the passphrase of the SECRET RSA KEY be obtained - brute forcing of which would be just as annoying as brute forcing the original password itself...

edit I wrote a small Python script for this, ssh-agent-sign

Tobias Kienzler
  • 7,658
  • 11
  • 43
  • 68
  • 2
    If I'm right, this is no more secure than just using the underlying hash algorithm. Stop trying to invent your own crypto and use something designed for password based key derivation. – ewanm89 Oct 29 '12 at 10:56
  • @ewanm89 What do you mean by that? A signature involves a secret (which is stored client-side in this case), while a hash does not involve secrets – Tobias Kienzler Oct 29 '12 at 11:00
  • except part of the signature is *public* and that can be used to decrypt back to the hash. DSA is not meant to hide information, that's what the hash part is for the rest of it just checks to see if it was the made by the private key you have the matching public key of. – ewanm89 Oct 29 '12 at 11:04
  • @ewanm89 I can't follow you there, the _entire_ signature is something you cannot generate without the private key (or quite some brute force) – Tobias Kienzler Oct 29 '12 at 11:19
  • @TobiasKienzler: using your method is no different than saving the resulting signature and entering it. The only difference is that you're generating the same signature over and over again. It looks secure to me, but it's only at first sight. I don't know the `ssh-agent` protocol (for example, how easy is it to make it sign arbitrary files on, some other, compromised system). – Hubert Kario Nov 02 '12 at 10:27
  • @HubertKario Comment's too short, I added a summary of that to the question's end. The signature is not supposed to be stored on the server, and the client doesn't have to establish any other kind of connection to forward the "password" (=signature) - in fact, if the signed message itself is stored on the server, the client doesn't even have enough information to generate that on its own... – Tobias Kienzler Nov 02 '12 at 10:37
  • @ewanm89 I'm not looking for password based key derivation, but for key based password derivation... Anyway, if you know of another solution (remote password generation via ssh) I'd to pleased to learn about that instead. – Tobias Kienzler Nov 02 '12 at 11:04
  • @TobiasKienzler "The signature is not supposed to be stored on the server" and that's the problem, it has to be stored there in memory to decrypt the drive, it can be extracted from there to completely compromise the whole encryption. – Hubert Kario Nov 02 '12 at 11:07
  • @HubertKario Sure, but that also would work locally - let's assume no cold boot attack or compromised server, which would screw up _any_ scheme anyway. What I meant was "not stored in a way easier to retrieve than memory storage" – Tobias Kienzler Nov 02 '12 at 11:11

3 Answers3

3

It's no less secure than entering a password over SSH to decrypt the container.

Whatever decrypting a container on a remote system is secure at all is completely different problem.

Hubert Kario
  • 3,748
  • 4
  • 27
  • 35
  • Is it really no less secure? Let's assume the server only stores MESSAGE and learns about the correct public key only by the agent's comment, would it really be equally risky that someone who compromised the server a) intercepts the password entered via SSH and b) connects to the agent's unix socket and let's it sign MESSAGE? Also, what would be the alternatives to remote-decryption in a multi-user environment, especially if the clients shouldn't be required to use separate software? – Tobias Kienzler Nov 06 '12 at 07:25
  • 1
    If the attacker can hijack ssh-agent session, he would be able to capture the password and vice versa. So the security of them is comparable. Key based allows for more entropy in encryption key but that's all. There are no alternatives to remote-decryption, there are no universal homomorphic encryption systems. – Hubert Kario Nov 06 '12 at 12:30
  • Isn't it easier to hijack the ssh-agent session (connecting to that unix socket as root) compared to extracting the passphrase from memory? Good point about allowing a higher entropy! – Tobias Kienzler Nov 08 '12 at 11:38
2

Here's my thoughts so far what an attacker could do:

  • Server-only attacks:
    • Agent: Obtain MESSAGE and connect to the ssh-agent's socket to obtain SIGNATURE. Can be mitigated by ssh-add -c, -x or -t
    • Both: Eavesdropping
    • Both: ... most things that would work locally, e.g. wrap the passphrase prompt, brute force the container passphrase (Agent method can easily chose a more complex one, while the private key passphrase can remain rather easy); cold boot attacks, or reading the passphrase from a running system's memory while the container is mounted
  • Client-also attacks:
    • Passphrase: Keylogger
    • Agent: Obtain the unencrypted private key

Anyway, here's an actual implementation for obtaining a signature: ssh-agent-sign (disclaimer: I wrote it)

Tobias Kienzler
  • 7,658
  • 11
  • 43
  • 68
1

Heh, I actually had the same idea for encrypting data on remote machines when I stumbled upon your question. I do not understand why you need to combine MESSAGE and SIGNATURE to create PASSWORD. Isn't SIGNATURE enough? If it isn't MESSAGE won't help. As I see it, the first thing that needs to be established is whether a signature is as strong a key as a private key. To establish that, a few things need to be determined:

  • Does the signature have the same entropy as the private key? - The signature length is always the same size as the key used. So with respect to key length the amount of entropy is unaffected.
  • Is a signature just as random as the key that was used? (I actually don't know)
  • Does the content of MESSAGE have any effect on the randomness of SIGNATURE? (Don't know that either)

Regarding MESSAGE: I think it would be wise to make it as random as possible using openssl rand (though, maybe not).

I do not see any problem with the protocol itself

A tip: Instead of piping the signature directly to something that you want to encrypt, you could decrypt the actual key (KEY) that should be used. This way you can allow multiple signatures to decrypt the same data (by saving the actual key multiple times encrypted with different signatures). So the protocol would look something like this.

Client:                   Server:
>ssh-add SECRET
>ssh -A server            
                          Locate keyfile for available signature
                          Ask ssh-agent to sign MESSAGE from keyfile with SECRET
ssh-agent returns SIGNATURE
                          Use SIGNATURE to decrypt PASSWORD from keyfile
                          Use PASSWORD to decrypt the actual data

I think I'll give it a go and try implementing this using socat and bash only, shouldn't be that hard :-)

andsens
  • 111
  • 2
  • It's been a while since I asked this question, actually I don't remember why MESSAGE and SIGNATURE where to be combined - probably in order to increase the possible PASSWORD complexity, though that would require MESSAGE being secured somehow as well... I never came around to actually implement this, so please feel free to update your answer if you do so – Tobias Kienzler Jun 05 '14 at 14:11
  • So, did you get around to implement this using `socat` and `bash` only? – Tobias Kienzler Oct 12 '15 at 11:38
  • @TobiasKienzler Unfortunately no :-/ – andsens Oct 13 '15 at 08:55
  • No worries - I wasn't too keen on learning `socat` and socket programming (yet), so I wrote a Python script [ssh-agent-sign](https://github.com/zommuter/ssh-agent-sign) for the same purpose (though there's some [uncertainty](https://github.com/zommuter/ssh-agent-sign/issues/4) on which part of paramiko's response is actually the signature and which part might vary) – Tobias Kienzler Oct 13 '15 at 17:18
  • Hah. That is cool. Gotta love the python libs that do all the work for you :-) – andsens Oct 14 '15 at 08:57
  • You _almost_ made this _not_ sound like I'm lazy :-P – Tobias Kienzler Oct 19 '15 at 07:46