Let's say you assign SSH keypairs to all users on your system; none of these "low trust" users have root privileges. You want the users to be able to use their keys in SSH connections, however, you don't want your users to be able to read their private keys.

This can be used to either prevent users from accessing secured servers over SSH from unauthorized computers (by copying their keypair to another computer), or to prevent their private keys being accidentally leaked.

Is there already this type of system in place for "hiding" private keys from the users, while still allowing them to use them during the shared key negotiation?

  • If there is such a system in place already, please make it clear in the answer if it built into the SSH specification, the OpenSSH implementation, or if it would require third-party tools.
    – IQAndreas
    Commented Dec 26, 2014 at 13:37
  • You should probably ask the sysadmins to set up ipsec if these are supposed to be secured servers.
    – Jim B
    Commented Dec 27, 2014 at 0:53

4 Answers 4


You are focusing on securing the keys on the client side. I would recommend that you take a look on the server side.

On the server, you can limit what they key is allowed to do and what servers it may be used from, by editing the authorized_keys file for the target account. Here's an example of a key with limits:

from="their.workstation.only.example.com" no-port-forwarding ssh-dss AAA....

You can use IP addresses instead of an FQDN if you like.

In order to prevent the users from tampering with the authorized_keys file, you can move it to a location where they do not have write permission. It will still work as long as they have read permission. This can be done by editing the sshd_config and changing

AuthorizedKeysFile .ssh/authorized_key

to e.g.

AuthorizedKeysFile /usr/local/authorized_keys/%u

The %u gets replaced by the username, so when someone connects to ssh with the username foo, ssh will look for the keyfile in /usr/local/authorized_keys/foo. As long as foo has read access to that file, the connection will work.

Edit: Instead of moving the key, you could simply set the file to immutable, like this:

sudo chattr +i /home/user/.ssh/authorized_keys

Once you've set up the source IP limitation, and you've secured the key file against tampering, it won't matter if the private key gets leaked - it still won't be usable from any other system.

There are a lot of other things you can do to limit the users when they connect with keys - see the man page for sshd. There's also been some questions about this at Serverfault, for example Limited SSH access for log retrieval.

  • 1
    Finally a step in the right direction! (and I hadn't thought about it, but perhaps I should have asked on ServerFault instead)
    – IQAndreas
    Commented Dec 26, 2014 at 15:11
  • I always assumed each line of authorized_keys was only allowed to contain the public key, not any additional data. Is there a list of all the possible values you can use in the file?
    – IQAndreas
    Commented Dec 26, 2014 at 15:13
  • 1
    The list is in the man page for sshd, under the heading Authorized Keys Format
    – Jenny D
    Commented Dec 26, 2014 at 15:39
  • I also thought of another way of keeping the authorized_keys file safe, see the edit. (And yeah, this is one question that overlaps between Information Security and Server Fault - I don't think this is the wrong place but maybe there are two right ones.)
    – Jenny D
    Commented Dec 26, 2014 at 15:41

I would suggest Smart Cards and secure tokens*. These have a storage that cannot be read, only be used from the secure cryptoprocessor. This means nobody that have full access to token can read the private key. The only thing user can do is to send a string to either be signed or decrypted, and get the result back.

The Smart card/secure token can also generate the keypair on the card, ensuring the key never has been, and can been outside of card/token. The public key can then be extracted to then be inserted into authorized keys.

*Secure USB tokens are effectively a Smart card and a Smart card reader, combined in the same chip with the same security level.

I would suggest a smart card and smart card reader, if multiple authorized users are gonna use the same terminal to connect to the SSH server under their own identity.

If each authorized users has their own terminal, or Group identities are used, then I would suggest using a PKI token, that can be permanently placed, and even locked with a padlock, inside the computer, and then connected to the computer using a internal USB Cable.


You can't remove it but you could encrypt it - without using the standard MD5 hashing:

cp /userdir/.ssh/id_rsa /userdir/.ssh/id_rsa.old
openssl pkcs8 -topk8 -v2 des3 -in /userdir/.ssh/id_rsa.old -out /userdir/.ssh/id_rsa
chmod 600 /userdir/.ssh/id_rsa

If you do so, openssl will ask you for a passphrase three times (to unlock the existing private key, and two more times for a passphrase for the new key). That is the manual method, or you can just use keycrypt

  • But that doesn't block the user access to the private key. If the user wants to use the key, they would have to know the symmetric password it is encrypted with; if they know the symmetric password, they could just as easily decrypt it themselves (and then copy it to a USB drive etc).
    – IQAndreas
    Commented Dec 26, 2014 at 14:17
  • The purpose of using keys most times is to avoid using a password/passphrase. When I use ssh keys for users who I don't want using a passphrase, they have no means to decrypt to begin with. They can log in because they have a key, but that does not allow them to see/decrypt a password
    – munkeyoto
    Commented Dec 26, 2014 at 14:20

There's a pretty fundamental problem here - you can't allow them to read the key in one circumstance, and then prevent them from doing something you don't want them to.

Even encrypting the key... if they've got the password to decrypt, then they can do what they like. And if they don't, they can't use it at all.

Faced with this problem, I would be suggesting you use a specific 'privilege account' for each user - give that the keypairs, and use sudo to allow specific commands to be run as that 'privilege user'. E.g. ssh $hostname. For bonus points, you can also enforce an ssh_config for that user account that they won't be able to change.

  • You don't have to allow them to read the key; if you put each user's key in a place only root can access it, you could have the SSH handshake (the symmetric key exchange) handled by a program with root access, which then hands the session key to the user when needed.
    – IQAndreas
    Commented Dec 26, 2014 at 14:54
  • The reason I asked the question is, I doubt I'm the first to come up with this idea; I wanted to know if a system like this was already in place before I go and re-invent the wheel.
    – IQAndreas
    Commented Dec 26, 2014 at 14:55

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .