如何使用 ssh-ed25519 作为 pysftp 的密钥来设置主机密钥文件
Posted
技术标签:
【中文标题】如何使用 ssh-ed25519 作为 pysftp 的密钥来设置主机密钥文件【英文标题】:How to set up a hostkey file using ssh-ed25519 as a key for pysftp 【发布时间】:2020-05-15 14:32:06 【问题描述】:我正在尝试使用pysftp
在我的 Python 脚本中连接到 SFTP 站点。
由于我没有 hostkey 文件,所以我按照here 的建议创建了一个“hostkey”,我正在尝试加载此文件,但 pysftp
没有连接到 sftp 站点.
python代码很简单:
cnopts = pysftp.CnOpts()
cnopts.hostkeys.load(pathToTheFile)
with pysftp.Connection(host, username=username, private_key=pathToPKey, cnopts=cnopts) as sftp:
#do things
我首先尝试在主机密钥文件中添加以下内容:
host.com ssh-ed25519 256 AZFsh0........Qy0=
但这会导致InvalidHostKey
错误和Incorrect padding
错误。我猜它不需要 256 作为密钥。所以,我删除了 256。
当我尝试不使用 256 时:
host.com ssh-ed25519 256 AZFsh0........Qy0=
然后它识别密钥,但出现'utf-8' codec can't decode byte 0x90 in position 11: invalid start byte
错误。
因此,我没有加载主机密钥文件,而是尝试按照here 中的建议使用以下代码添加主机密钥:
keydata = b"""AZFsh0........Qy0="""
key1 = paramiko.ed25519key.Ed25519Key(data=keydata)
key2 = paramiko.ed25519key.Ed25519Key(data=base64.b64decode(keydata))
key3 = paramiko.ed25519key.Ed25519Key(data=base64.b64decode(keydata).hex())
key4 = paramiko.ed25519key.Ed25519Key(data=decodebytes(keydata))
key5 = paramiko.ed25519key.Ed25519Key(data=decodebytes(keydata).hex())
cnopts.hostkeys.add("host.com", "ssh-ed25519", key1)
我尝试使用上述所有键,但仍然收到Incorrect padding
之类的错误,
我看到有人提到this may be a bug,但该帖子来自 2018 年。 有谁知道这是不可行的还是我遗漏了什么?
编辑(这工作)
Connection to an SFTP server using pysftp and Python 3 with just the server fingerprint 中发布的解决方案在Martin Prikryl 的回复中的链接中链接有效。
这是我使用的(我已经清理了一些以删除未使用的功能)。
import hashlib as hl
#Removed trim_fingerprint() and clean_fingerprint() because it wasn't necessary in my case
class FingerprintKey:
def __init__(self, fingerprint):
self.fingerprint = fingerprint
def compare(self, other):
if callable(getattr(other, "get_fingerprint", None)):
return other.get_fingerprint() == self.fingerprint
elif other == self.get_fingerprint():
return True
elif hl.md5(other).hexdigest() == self.fingerprint:
return True
else:
return False
def __cmp__(self, other):
return self.compare(other)
def __contains__(self, other):
return self.compare(other)
def __eq__(self, other):
return self.compare(other)
def __ne__(self, other):
return not self.compare(other)
def get_fingerprint(self):
return self.fingerprint
def get_name(self):
return u'ssh-ed25519' # Including "256" errors out.
def asbytes(self):
return self
而且是这样使用的:
cnopts = pysftp.CnOpts()
cnopts.hostkeys.add('host.com', u'ssh-ed25519 256', FingerprintKey("e2d1............c957")) # Removed ":" from the MD5 value
我苦苦挣扎的主要问题是我不确定应该为cnopts.hostkeys.add
等插入什么值,所以我会提供这些细节以防有人对此不熟悉。
就我而言,我使用 WinSCP 来获取主机密钥指纹。
-
打开 WinSCP
输入主机名、用户名,并指定要连接的私钥路径
点击会话
点击服务器/协议信息
使用算法中的值作为
cnopts.hostkeys.add
的第二个参数(keytype
)
使用 MD5 中的值作为cnopts.hostkeys.add
的第三个参数 (key
)。实际值带有冒号(例如 e2:d1:......c9:57),但正如 Connection to an SFTP server using pysftp and Python 3 with just the server fingerprint 的作者所提到的,我也必须手动删除冒号。
【问题讨论】:
【参考方案1】:进入“主机密钥文件”的是完整的主机/公钥,而不仅仅是指纹。
详情见(再次):Verify host key with pysftp
如果您只想使用指纹验证主机密钥,请参阅:Python - pysftp / paramiko - Verify host key using its fingerprint (尽管这已经在第一个答案中链接了)。
【讨论】:
以上是关于如何使用 ssh-ed25519 作为 pysftp 的密钥来设置主机密钥文件的主要内容,如果未能解决你的问题,请参考以下文章
如何以通过 ed25519 识别的用户身份使用 MYSQL Workbench 连接到 MariaDB (10.5.8)?
如何使用 Bouncy Castle 创建与 OpenSSH 兼容的 ED25519 密钥?