Paramiko -- using encrypted private key file on OS X

The RSAKey.from_private_key_file() is inherited from PKey(); an optional parameter of this method is a password. To quote:

If the private key is encrypted and password is not None, the given password will be used to decrypt the key (otherwise PasswordRequiredException is thrown).

As you're not passing a password and your key is encrypted this exception will always be thrown. There's only one way round this problem, to actually give the method a password. You, therefore, need a way of getting the password out of the OSXKeychain.

You could use the cross-platform Keyring module to do this.


The following approach seems to work fine (on OS X, with the usual setup of encrypted private keys that have passphrases stored in the keychain, without any user interaction):

import paramiko

ssh = paramiko.SSHClient()
ssh.load_system_host_keys()
ssh.connect(HOST, username=USER, look_for_keys=False)
...
ssh.close()

It seems that look_for_keys=False is not absolutely necessary. However, if you use it you will get much better error messages in the case of an authentication failure ("AuthenticationException" instead of "PasswordRequiredException").


If you really want to use private keys directly, you could do the following:

import os
import paramiko
import keyring

keyfile = os.path.expanduser('~/.ssh/id_rsa')
password = keyring.get_password('SSH', keyfile)
key = paramiko.RSAKey.from_private_key_file(keyfile, password=password)

However, based on my testing, this is not needed. The above solution that uses ssh.connect in a straightforward manner should be sufficient.