使用Python Paramiko对SFTP服务器进行双因素(按键和键盘交互)身份验证

使用Python Paramiko对SFTP服务器进行双因素(按键和键盘交互)身份验证,python,ssh,sftp,paramiko,pysftp,Python,Ssh,Sftp,Paramiko,Pysftp,我试图通过Python中的安全SFTP连接到服务器,但我不断收到身份验证错误。我确信我有正确的详细信息,因为我可以通过WinSCP连接。很好: 我还查看了Paramiko日志文件的输出,它说密码验证失败,但我确信密码是正确的,我的代码 下面是我正在使用的代码,它是从各种stackoverflow帖子拼凑而成的。知道为什么它不能连接吗 import paramiko import pysftp from base64 import decodebytes host = '<my serv

我试图通过Python中的安全SFTP连接到服务器,但我不断收到身份验证错误。我确信我有正确的详细信息,因为我可以通过WinSCP连接。很好:

我还查看了Paramiko日志文件的输出,它说密码验证失败,但我确信密码是正确的,我的代码

下面是我正在使用的代码,它是从各种stackoverflow帖子拼凑而成的。知道为什么它不能连接吗

import paramiko
import pysftp
from base64 import decodebytes

host = '<my server address>'
port = 6671
user = '<my username>'
password = '<my password>'
private_key = '<location of my private key file>'
host_key_data = b"""<contains my host key data>"""
host_key = paramiko.RSAKey(data=decodebytes(host_key_data))
cnopts = pysftp.CnOpts()
cnopts.hostkeys.add(host, 'ssh-rsa', host_key)
pysftp.Connection(host, username=user, password=password, private_key=private_key, port=port, cnopts=cnopts)
导入paramiko
导入PYSTFP
从base64导入解码字节
主机=“”
端口=6671
用户=“”
密码=“”
私钥=“”
主机密钥数据=b“”
主机密钥=paramiko.RSAKey(数据=解码字节(主机密钥数据))
cnopts=pysftp.cnopts()
添加(主机,'ssh rsa',主机密钥)
连接(主机,用户名=用户,密码=密码,私钥=私钥,端口=端口,cnopts=cnopts)
日志文件的输出:

DEB[20190626-12:51:16.270]thr=4 paramiko.transport:Kex同意:diffie-hellman-group-exchange-sha256
DEB[20190626-12:51:16.271]thr=4 paramiko.transport:同意的主机密钥:ssh rsa
DEB[20190626-12:51:16.272]thr=4 paramiko.运输:同意密码:aes128中心
DEB[20190626-12:51:16.273]thr=4帕拉米科。运输:MAC同意:hmac-sha1
DEB[20190626-12:51:16.274]thr=4 paramiko.运输:压缩同意:无
DEB[20190626-12:51:16.774]thr=4 paramiko.transport:Got服务器p(1024位)
DEB[20190626-12:51:17.029]thr=4 paramiko.transport:kex引擎KexGexSHA256指定哈希算法
DEB[20190626-12:51:17.030]thr=4 paramiko.transport:切换到新键。。。
DEB[20190626-12:51:17.032]thr=2 paramiko.transport:主机密钥已验证(ssh rsa)
DEB[20190626-12:51:17.032]thr=2 paramiko.transport:正在尝试密码验证。。。
DEB[20190626-12:51:17.531]thr=4 paramiko.transport:userauth正常
INF[20190626-12:51:17.532]thr=4 paramiko.transport:Auth banner:b'FactSet文件传输系统(FTS)\n'
INF[20190626-12:51:17.767]thr=4 paramiko.transport:身份验证(密码)失败。
使用WinSCP.NET程序集的VBA代码,该程序集可用于:

设置会话选项 将mySessionOptions设置为新会话选项 使用mySessionOptions .Protocol=协议 .HostName=“” .PortNumber=6671 .UserName=“” .Password=“” .SshHostKeyFingerprint=“ssh rsa 2048指纹密钥” .SshPrivateKeyPath=“私钥文件的位置” 以
!2019-06-27 17:24:18.691使用代理提供的公钥“factset-rsa-key-20170717”进行身份验证
. 2019-06-27 17:24:18.756发送选美响应
! 2019-06-27 17:24:19.260需要进一步认证
. 2019-06-27 17:24:19.266需要进一步认证
. 2019-06-27 17:24:19.500提示(5,SSH服务器:密码验证,使用键盘交互验证,密码:)
. 2019-06-27 17:24:19.505使用存储的密码。
您正在WinSCP中使用双因素身份验证(键和键盘交互)

恐怕PYSTFP不支持双因素身份验证

直接使用,它支持多因素身份验证。pysftp在内部使用Paramiko

实现全键盘交互式身份验证可能比其他身份验证类型要复杂一些。但由于服务器通常使用键盘交互身份验证来请求单个固定密码,因此一些SSH库为这种情况提供了快捷方式。WinSCP.NET程序集在VBA脚本中也会执行此操作(您可以指定
密码
,尽管WinSCP执行键盘交互身份验证,而不是密码身份验证)。帕拉米科也是这样做的。如果使用Paramiko的
password
参数,Paramiko将使用指定的密码响应第一个键盘交互式身份验证提示

ssh = paramiko.SSHClient()
# ... 
ssh.connect(host, username=user, port=port, password=password, key_filename=private_key)

您还必须验证服务器的主机密钥(与pysftp和WinSCP中的验证方法相同)。

有关Paramiko解决方案,请参阅。

我认为您应该使用(用户名、密码)或(用户名、私钥)。它们三个可能无法正常工作,因为这并不是因为我尝试使用username,private_key成功地创建了一个连接对象,但是当在我知道服务器上存在的文件上运行
sftp.isfile('filename')
时,我得到一个
Oops,未处理的类型3('unimplemented')
错误消息。似乎也不能使用put或get命令我肯定在WinSCP中使用SFTP,我现在正试图使用python代码进行连接。我有私钥文件和主机密钥指纹。哦,太糟糕了。帕拉米科有一只猫。也许这是一条更好的路线?我在winscp登录页面上贴了一张图片,上面的细节被遮住了