首页 > 解决方案 > 无法使用注册表中的主机密钥使用 pySFTP 连接到 EFT 服务器

问题描述

我对这段代码完全不知所措。我正在尝试设置一个脚本来定期将文件从 EFT 服务器传输到本地文件夹。我正在使用 pySFTP,从外观上看,文件传输代码非常简单。

但是,由于主机密钥问题,我无法连接到 EFT 服务器。我不熟悉主机键的工作原理,尽管阅读了很多关于它的内容,但我仍然不确定我是否理解它。我已经尝试过 Martin Prikryl 的第一个代码。我已经用占位符替换了实际的登录详细信息,因为这是一个工作服务器,所以不能在这里分享,但是我 100% 确定我使用的是正确的:

import pysftp
import paramiko
from base64 import decodebytes

keydata = b"""0x11,0xc83f438e85c279c64150c44db874ab091267f38a69843dbdfb0d5b729109b4db64c706af00a68f243740149afa1c3022ebb5435904256229f5820050678361a2880bdb8934d4876c8383d4bd457b74397178880c9ae669645d778510e3ff1dcc1ac91ab43701fda075afaab49a0c3526bd98e848895221791c68b4aa98fe196f2e7ba998a713d48608f38c2699dc8b8d1bd70bedee143a7aad1fd6b2409c77588bc0d9dd2fecae9cf272a0242f2080f5054e78a100a94fda577bdab18ba75676aa999d2dd31c3df56c62cbd6e45aa5bffcb44de2ef129dfe97f6bf6d6d51032fe138950409168c003d3d316588b40ba97b5cc8122d0a323bd809bc3c53074bdb"""
key = paramiko.RSAKey(data=decodebytes(keydata))
cnopts = pysftp.CnOpts()
cnopts.hostkeys.add('HOST', 'rsa2022', key)

host = "HOST"
username = "USER"
password = "PASS"

with pysftp.Connection(host, username, password, cnopts=cnopts) as sftp:
    print("Connection established...")

由于填充问题,此操作失败。我通过使用 Putty 连接到服务器获得了此密钥,该服务器将密钥保存到我的注册表中。我也尝试过使用服务器所有者提供的密钥:

import pysftp
import paramiko
from base64 import decodebytes

keydata = b"""e1:98:d0:0e:85:f8:51:23:87:fa:24:4b:7e:81:88:e8"""
key = paramiko.RSAKey(data=decodebytes(keydata))
cnopts = pysftp.CnOpts()
cnopts.hostkeys.add('HOST', 'ssh-rsa', key)

host = "HOST"
username = "USER"
password = "PASS"

with pysftp.Connection(host, username, password, cnopts=cnopts) as sftp:
    print("Connection established...")

这给了我一个错误提示 - UnicodeDecodeError: 'utf-8' codec can't decode bytes in position 2-3: invalid continuation byte - 我不确定。我试过删除冒号,但我得到了同样的错误。

我尝试了 5 或 6 种不同的解决方案,我最大的问题是,Putty 已将主机密钥存储在我的注册表中,而 pySFTP 或 Paramiko(据我所知)无法在那里访问它。

我已经研究过自己创建一个 known_hosts 文件以供 pySFTP 参考,但找不到任何明确的方法。

诚然,这是比我习惯的更高级的 Python,但它想要主机密钥的方式让我完全困惑。如果有人可以提出解决方案或替代方案来尝试,我愿意接受所有建议。

标签: python-3.xparamikopysftp

解决方案


非常感谢您的帮助 Martin Prikryl。我使用了 ssh-keyscan(尽管我有权限,但它让我在 cmd 提示符下使用它)并获得了真正的主机密钥。然后在您的代码中使用 pySFTP 验证主机密钥!

因此,为了回答我自己的问题,这是我的工作代码,其中 HOSTKEY 是在命令提示符下通过 ssh-keyscan 收集的密钥:

import pysftp
import paramiko
from base64 import decodebytes

keydata = b"""HOSTKEY"""
key = paramiko.RSAKey(data=decodebytes(keydata))
cnopts = pysftp.CnOpts()
cnopts.hostkeys.add('HOST', 'ssh-rsa', key)

myHost = "HOST"
myUsername = "USER"
myPassword = "PASSWORD"

with pysftp.Connection(host=myHost, username=myUsername, password=myPassword, cnopts=cnopts) as sftp:
    print("Connection established...")

我仍然不知道如何创建或填充 known_hosts 文件,但是在 cmd 提示符下尝试“> known_hosts”命令会导致访问被拒绝,所以我完全有可能无法访问它将存储的位置. 此代码将在只有我可以访问的安全机器上运行,所以这不是一个大问题。


推荐阅读