SFTP服务器需密码+私钥双重认证,Python代码连接失败求助
SFTP双重认证(密码+私钥)连接问题解决方案
问题根源
Paramiko(以及基于它的pysftp)在connect方法中同时传入password和pkey时,会优先尝试公钥认证,认证通过后就不会触发密码认证,无法满足服务器要求的双重认证流程。
Paramiko 解决方案
需要手动分步完成公钥认证和密码认证,而非依赖connect的自动认证逻辑:
import paramiko # 初始化SSH客户端 client = paramiko.client.SSHClient() client.set_missing_host_key_policy(paramiko.AutoAddPolicy()) # 建立未认证的基础连接(禁止自动查找本地密钥、禁用代理) client.connect( hostname='sftp.example.com', username='username', port=22, look_for_keys=False, allow_agent=False ) # 加载本地私钥 private_key = paramiko.RSAKey.from_private_key_file('private_key_path') # 获取传输层对象,执行两步认证 transport = client.get_transport() # 第一步:公钥认证 transport.auth_publickey(username='username', key=private_key) # 第二步:密码认证(顺序可根据服务器要求调整,若WinSCP先输密码则调换顺序) transport.auth_password(username='username', password='password') # 打开SFTP会话并执行操作 sftp = client.open_sftp() sftp.put('test.txt', '/tmp/test.txt') # 示例:上传文件 # 关闭资源 sftp.close() client.close()
Pysftp 解决方案
Pysftp底层依赖Paramiko,同样需要手动调用传输层的认证方法,同时注意修正代码中的用户名拼写错误(原代码中usernmae少了字母r):
import pysftp import paramiko cnopts = pysftp.CnOpts() cnopts.hostkeys = None # 建立基础连接 with pysftp.Connection( hostname='sftp.example.com', username='username', # 修正原代码的拼写错误 port=22, cnopts=cnopts, look_for_keys=False, allow_agent=False ) as sftp: # 获取底层传输层对象 transport = sftp.get_channel().get_transport() # 加载私钥 private_key = paramiko.RSAKey.from_private_key_file('private_key_path') # 执行双重认证 transport.auth_publickey('username', private_key) transport.auth_password('username', 'password') # 执行SFTP操作 sftp.put('test.txt', '/tmp/test.txt')
注意事项
- 私钥文件权限需符合要求:Linux/macOS下建议设置为
chmod 600 private_key_path,避免权限过高被服务器拒绝。 - 认证顺序需匹配服务器配置:若WinSCP操作时先输入密码再选择私钥,需调换
auth_password和auth_publickey的执行顺序。 - 检查代码中的拼写错误:原pysftp代码中用户名
usernmae为拼写错误,需修正为正确的username。
内容的提问来源于stack exchange,提问作者srikanth gunuputi
相关产品推荐
相关产品推荐

