Ssh Paramiko——在OSX上使用加密的私钥文件

Ssh Paramiko——在OSX上使用加密的私钥文件,ssh,osx-mountain-lion,paramiko,private-key,Ssh,Osx Mountain Lion,Paramiko,Private Key,我正在尝试使用Paramiko从Python连接到SSH服务器。这就是我迄今为止所尝试的: >>> import paramiko >>> import os >>> privatekeyfile = os.path.expanduser('~/.ssh/id_rsa') >>> mykey = paramiko.RSAKey.from_private_key_file(privatekeyfile) Traceback (

我正在尝试使用Paramiko从Python连接到SSH服务器。这就是我迄今为止所尝试的:

>>> 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
导入paramiko >>>导入操作系统 >>>privatekeyfile=os.path.expanduser(“~/.ssh/id\u rsa”) >>>mykey=paramiko.RSAKey.from_private_key_文件(privatekeyfile) 回溯(最近一次呼叫最后一次): 文件“”,第1行,在 文件“/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site packages/paramiko/pkey.py”,第198行,在from_private_key_文件中 key=cls(文件名=文件名,密码=密码) 文件“/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site packages/paramiko/rsakey.py”,第51行,在__ self.\来自\u私有\u密钥\u文件(文件名、密码) 文件“/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site packages/paramiko/rsakey.py”,第163行,在私有密钥文件中 data=self.\u读取\u私钥\u文件('RSA',文件名,密码) 文件“/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site packages/paramiko/pkey.py”,第280行,在_read_private_key_文件中 data=self.\u读取\u私钥(标签、f、密码) 文件“/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site packages/paramiko/pkey.py”,第323行,在_read_private_key中 引发PasswordRequiredException('私钥文件已加密') paramiko.PasswordRequiredException:私钥文件已加密
正如您所看到的,它失败了,因为我的私钥是加密的。但是,密码存储在我的OS X登录密钥链中,当我键入
ssh host
时,它不会请求密码(相反,它只请求一次,然后在下次重新启动之前记住密码)。有没有办法让
paramiko
ssh
那样使用密码/从密钥链获取密码?

RSAKey.from_private_key_file()是从中继承的;此方法的可选参数是密码。引述:

如果私钥已加密且密码不是None,则给定的 密码将用于解密密钥(否则为 将引发PasswordRequiredException)

由于您没有传递密码,并且您的密钥已加密,因此将始终引发此异常。解决这个问题的方法只有一个,就是给这个方法一个密码。因此,您需要一种从OSXKeychain中获取密码的方法


您可以使用跨平台模块来实现这一点。

以下方法似乎可以正常工作(在OS X上,使用通常的加密私钥设置,密钥链中存储有密码短语,无需任何用户交互):

似乎并非绝对必要。但是,如果您使用它,在身份验证失败的情况下会得到更好的错误消息(“AuthenticationException”而不是“PasswordRequiredException”)


如果确实希望直接使用私钥,可以执行以下操作:

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)

然而,根据我的测试,这是不必要的。上述以简单方式使用ssh.connect的解决方案应该足够了。

在Paramiko中使用加密私钥是不可能的,因为(没有内存转储)

解决方案是使用
子流程
并从中调用ssh命令(与任何常规命令一样)。它并没有要求解密私钥(它使用ssh代理,您可以使用
ssh-vvv

顺便说一句,我找不到使用
paramiko
的好处。SSH代理似乎更成熟,更通用。例如,在帕拉米科,必须求助于子流程。另请注意2014年的“钥匙处理不良”(开放):

SSHClient.\u auth使用多出口策略,并结合存储单个异常,以在流程结束时引发。这通常意味着在身份验证时引发的异常对于无法进行身份验证的真正原因是完全不正确的

此线程中链接了许多paramiko bug。它现在似乎正在积极开发中,我希望paramiko能解决这个问题,但我的建议是:不要依赖一个库,它可能无法满足您的需求


是的,有可能为加密密钥提供密码,但这违背了其目的。您可以自己输入密码(然后您不需要ssh密钥),或者将密码存储在磁盘上(当然不在版本控制中),然后您不需要对私钥进行加密(这样做的想法是,如果有人获得您的HDD,就不会以纯文本形式获得您的私钥).

我最终只是创建了一个没有密码的新密钥对并使用了它,但接受了它,因为这可能会起作用,这是我自己在houbysoft遇到这种情况时的解决方案。。。它只是没有回答问题:-)。那么,密码被用作密码短语die decrypting?因为我刚试过,但没用!无法从ssh代理获取私钥(没有内存转储)。我在您的第一种方法中遇到了这个错误:没有可用的身份验证方法keyring.get_password('SSH',keyfile)-不幸的是,这在Gnome keyring(Fedora 29)中对我不起作用。这似乎是不可能的。我列出了gnome密钥环标签,但是SSH不在那里,并且相应的标签不能与
keyring
一起使用。顺便说一句,不可能从SSH代理获取私钥(没有内存转储)。您如何使用
对象?
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)