You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Python pysftp/paramiko连接SFTP报no acceptable ciphers错误如何解决

问题根因

从提供的paramiko调试日志可直接定位两个核心问题:

  1. 依赖库版本兼容缺陷:你使用的pysftp==0.2.9已停止维护超过6年,存在多处传参与适配bug:按位置传递的加密算法列表无法正确注入到底层paramiko的Transport实例、默认硬编码的加密算法列表过旧、无法自动加载ED25519格式的私钥。从调试日志可见,你手动传入的aes-ctr、aes-cbc类算法完全没有出现在客户端发起协商的加密列表中,证明参数传递完全失效。
  2. 服务端配置查询方式错误:你执行ssh -Q cipher查询到的是服务器本地SSH客户端编译支持的所有加密算法,不是sshd服务实际运行时允许的加密算法列表,查询结果和服务端真实配置不匹配,导致你手动指定的算法可能根本不在服务端允许范围内。
排查思路

按优先级依次验证:

  • 登录Rocky Linux服务器,执行sshd -T | grep ciphers获取sshd服务实际启用的加密算法列表,确保客户端配置的算法和该列表存在至少一个交集
  • 确认本地私钥格式为标准OpenSSH格式,而非Putty生成的.ppk格式,若为ppk格式需先转换为OpenSSH格式
  • 确认服务器端/home/pmartin/.ssh/authorized_keys文件权限为600,所属用户和用户组均为pmartin,避免sshd因权限过宽拒绝密钥认证
  • 若服务器开启SELinux,执行restorecon -Rv /home/pmartin/.ssh修复.ssh目录的安全上下文
  • 确认Windows本地运行Python的用户对私钥文件有读权限
解决方案

优先选择方案1,无兼容层bug,稳定性最高。

方案1:弃用pysftp,直接基于paramiko实现

pysftp本身只是paramiko的薄封装,停更后已无法适配新版OpenSSH和paramiko的特性,直接使用paramiko可完全控制连接参数,避免中间层bug。
可直接运行的示例代码:

import paramiko
import logging

# 开启调试日志,连接异常时可直接看到协商过程
logging.basicConfig(level=logging.DEBUG)
paramiko.common.logging.basicConfig(level=paramiko.common.DEBUG)

# 连接配置
host = 'monServeur.domaine.fr'
port = 22
username = 'pmartin'
# Windows路径使用原始字符串避免转义问题
pkey_path = r'C:\Users\pmartin\.ssh\myPrivateKey'
passphrase = 'mypassphrase'

# 配置全量兼容加密算法列表,确保和服务端有交集
ciphers = [
    'aes256-gcm@openssh.com',
    'aes128-gcm@openssh.com',
    'chacha20-poly1305@openssh.com',
    'aes256-ctr',
    'aes192-ctr',
    'aes128-ctr',
    'aes256-cbc',
    'aes192-cbc',
    'aes128-cbc'
]

# 初始化传输通道,手动指定加密算法
transport = paramiko.Transport((host, port))
transport.get_security_options().ciphers = ciphers

# 加载带口令的私钥,根据你的私钥类型选择对应的类:RSA密钥用RSAKey,ED25519密钥用Ed25519Key
private_key = paramiko.Ed25519Key.from_private_key_file(pkey_path, password=passphrase)
# private_key = paramiko.RSAKey.from_private_key_file(pkey_path, password=passphrase)

# 建立连接
transport.connect(username=username, pkey=private_key)

# 初始化SFTP客户端执行业务操作
sftp = paramiko.SFTPClient.from_transport(transport)
sftp.chdir('/home/pmartin')
for entry in sftp.listdir_attr():
    print(entry.filename)

# 释放资源
sftp.close()
transport.close()

方案2:保留pysftp依赖,修复传参逻辑

如果必须使用pysftp,需要放弃位置传参,全部使用关键字传参,同时手动加载私钥、通过CnOpts配置加密算法:

import pysftp
import paramiko

host = 'monServeur.domaine.fr'
port = 22
username = 'pmartin'
pkey_path = r'C:\Users\pmartin\.ssh\myPrivateKey'
passphrase = 'mypassphrase'

# 兼容加密算法列表
ciphers = [
    'aes256-gcm@openssh.com',
    'aes128-gcm@openssh.com',
    'chacha20-poly1305@openssh.com',
    'aes256-ctr',
    'aes192-ctr',
    'aes128-ctr'
]

# 手动加载私钥,适配RSA/ED25519格式
key = paramiko.Ed25519Key.from_private_key_file(pkey_path, password=passphrase)
# key = paramiko.RSAKey.from_private_key_file(pkey_path, password=passphrase)

# 配置连接参数
cnopts = pysftp.CnOpts()
cnopts.ciphers = ciphers

with pysftp.Connection(
    host=host,
    port=port,
    username=username,
    private_key=key,
    private_key_pass=passphrase,
    cnopts=cnopts
) as sftp:
    with sftp.cwd('/home/pmartin'):
        for entry in sftp.listdir_attr():
            print(entry.filename)

内容的提问来源于stack exchange,提问作者Olivier MM

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.27 22:06:51