Paramiko ― using encrypted private key file on OS X

匿名 (未验证) 提交于 2019-12-03 03:04:01

问题:

I'm trying to use Paramiko to connect to an SSH server from Python. This is what I tried so far:

>>> import paramiko >>> import os >>> privatekeyfile = os.path.expanduser('~/.ssh/id_rsa') >>> mykey = paramiko.RSAKey.from_private_key_file(privatekeyfile) Traceback (most recent call last):   File "<stdin>", line 1, in <module>   File "/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/paramiko/pkey.py", line 198, in from_private_key_file     key = cls(filename=filename, password=password)   File "/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/paramiko/rsakey.py", line 51, in __init__     self._from_private_key_file(filename, password)   File "/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/paramiko/rsakey.py", line 163, in _from_private_key_file     data = self._read_private_key_file('RSA', filename, password)   File "/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/paramiko/pkey.py", line 280, in _read_private_key_file     data = self._read_private_key(tag, f, password)   File "/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/paramiko/pkey.py", line 323, in _read_private_key     raise PasswordRequiredException('Private key file is encrypted') paramiko.PasswordRequiredException: Private key file is encrypted 

As you can see, it's failing because my private key is encrypted. However, the password is stored in my OS X login keychain, and when I type ssh host it won't ask for it (rather, it only asks once, then remembers it until the next reboot). Is there a way to make paramiko use the password / fetch it from the keychain, like ssh does?

回答1:

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.



回答2:

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.



标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!