Must I store a private key in a file?

If you want to use the existing tools like ssh/ssh-agent you have to provide the key as a file.

Another, maybe more feasible solution is to either directly implement a ssh client within your application and depend on third party libraries such as JSch or extend either ssh/ssh-agent to directly receive and decrypt the key from your database.


Files are the main way to exchange data between applications. It doesn't have to be a disk file. It can be a file on temporary storage or a pipe. You can feed a key file to ssh-add on its standard input, as long as the key file isn't password-protected¹ (and since the key file was stored encrypted, there's no reason for it to be password-protected on top).

Alternatively, don't do anything fancy and write the file to a memory-backed filesystem such as /run (or /dev/shm or /tmp or whatever your distribution offers).

Alternatively, keep the private key file around with no external encryption, but put a password on it. Use a long, randomly-generated passsword, and store that password in the database.

¹ Experimentally, ssh-add chokes on password-protected key files that aren't seekable, such as named pipes.


Sorry, not an answer but too long for a comment, which I think is in place.

Important thing is what you are trying to achieve by storing the key in the database encrypted.

An attacker that is able to access the temporary private key file will be able to read the ssh client process' memory as well (and hence get to the key data anyway), because both of these data must have basically the same access permissions - trying to hide the file doesn't seem to make it any more secure.

If you are using different users for db, webapp and ssh connection, by storing the key in the db, decrypting it in the webapp and feeding it to ssh, you are just opening potential attack vectors by spreading the key all over the process. If you are using just one user for all of these (db, app, ssh), you are gaining nothing except for code complexity.

The only advantage seems to be an easier transfer of the system to a different host and potential gain in case the db data gets stolen but the webapp (which AFAIU contains the decryption algorithm and password) not. But is that likely?

That said, if you want to protect the key, you can also use the ssh's internal encryption of the keys and load them into an ssh-agent when starting your service (remember to remove it when it stops!). But again remember that the ssh-agent keeps the keys in memory unencrypted, so it can potentially be read. Yet again: is this the problem you are trying to solve?

If you just need to protect communication between two machines, stunnel might be of better service than ssh.

And finally for the question: as far as OpenSSH (portable) is concerned, writing a simple patch that would allow ssh to read the key from another process as sshd does with the AuthorizedKeysCommand option should be reasonably straightforward.