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

Python使用ftplib连接FTPS时遇SSL:SSLV3_ALERT_HANDSHAKE_FAILURE错误求助

FTPS显式加密连接失败(SSL: SSLV3_ALERT_HANDSHAKE_FAILURE),WinSCP可正常连接

我用Python的ftplib库连接采用TLS/SSL显式加密的FTPS站点时,一直收到SSL: SSLV3_ALERT_HANDSHAKE_FAILURE错误,但WinSCP能正常连接。试过网上多种配置方案都没解决,求帮助。

我的代码

ftp = FTP_TLS()
ftp.debugging = 2
ftp.connect('xxx.xxxx.xxx', 990)
ftp.auth()
ftp.prot_p()
ftp.login('username', 'password')

报错信息

ssl.SSLError: [SSL: SSLV3_ALERT_HANDSHAKE_FAILURE] sslv3 alert handshake failure (_ssl.c:997)

服务器及协议信息(来自WinSCP)

Remote system = UNIX Type: L8
File transfer protocol = FTP
Cryptographic protocol = TLS/SSL Explicit encryption, TLSv1
Encryption algorithm = SSLv3: DHE-RSA-AES256-SHA, 2048 bit RSA, DHE-RSA-AES256-SHA      SSLv3 Kx=DH       Au=RSA  Enc=AES(256)  Mac=SHA1

WinSCP日志

< 2023-04-06 21:34:57.065 Script: Connecting to xxx.xxx.xxx:990 ...
. 2023-04-06 21:34:57.065 Connecting to xxx.xxx.xxx:990 ...
. 2023-04-06 21:34:57.115 Connected with xxx.xxx.xxx:990, negotiating TLS connection...
< 2023-04-06 21:34:57.280 220 ProFTPD 1.3.2 Server (xxx.xxx.xxx) [::ffff:xxx.xxx.xxx]
> 2023-04-06 21:34:57.280 AUTH TLS
< 2023-04-06 21:34:57.326 234 AUTH TLS successful
. 2023-04-06 21:34:57.645 Verifying certificate for "Company" with fingerprint fa:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx: and 20 failures
. 2023-04-06 21:34:57.645 Certificate common name "xxx.xxx.xxx" matches hostname
. 2023-04-06 21:34:57.645 Certificate for "Company" matches configured fingerprint
. 2023-04-06 21:34:57.645 Using TLSv1, cipher SSLv3: DHE-RSA-AES256-SHA, 2048 bit RSA, DHE-RSA-AES256-SHA      SSLv3 Kx=DH       Au=RSA  Enc=AES(256)  Mac=SHA1
< 2023-04-06 21:34:57.645 Script: TLS connection established. Waiting for welcome message...
. 2023-04-06 21:34:57.645 TLS connection established. Waiting for welcome message...
> 2023-04-06 21:34:57.645 USER UserName
< 2023-04-06 21:34:57.698 331 Password required for UserName
> 2023-04-06 21:34:57.698 PASS ********
< 2023-04-06 21:34:57.795 230 User UserName logged in
> 2023-04-06 21:34:57.795 SYST
< 2023-04-06 21:34:57.841 215 UNIX Type: L8
> 2023-04-06 21:34:57.841 FEAT
< 2023-04-06 21:34:57.885 211-Features:
< 2023-04-06 21:34:57.885  MDTM
< 2023-04-06 21:34:57.885  MFMT
< 2023-04-06 21:34:57.885  AUTH TLS
< 2023-04-06 21:34:57.885  MFF modify;UNIX.group;UNIX.mode;
< 2023-04-06 21:34:57.885  MLST modify*;perm*;size*;type*;unique*;UNIX.group*;UNIX.mode*;UNIX.owner*;
< 2023-04-06 21:34:57.885  PBSZ
< 2023-04-06 21:34:57.885  PROT
< 2023-04-06 21:34:57.885  REST STREAM
< 2023-04-06 21:34:57.885  SIZE
< 2023-04-06 21:34:57.979 211 End
> 2023-04-06 21:34:57.979 PBSZ 0
< 2023-04-06 21:34:58.023 200 PBSZ 0 successful
> 2023-04-06 21:34:58.023 PROT P
< 2023-04-06 21:34:58.067 200 Protection set to Private
< 2023-04-06 21:34:58.067 Script: Connected
. 2023-04-06 21:34:58.067 Connected

Python调试日志

*get* '220 ProFTPD 1.3.2 Server (xxx.xxx.xxx) [::ffff:xxx.xxx.xxx]\n'
*resp* '220 ProFTPD 1.3.2 Server (xxx.xxx.xxx) [::ffff:xxx.xxx.xxx]'
*cmd* 'AUTH TLS'
*put* 'AUTH TLS\r\n'
*get* '234 AUTH TLS successful\n'
*resp* '234 AUTH TLS successful'
Traceback (most recent call last):
  File "C:\Path\Python\Sandbox_FTP_TLS_Explicit.py", line 17, in <module>
    ftp = connect()
  File "C:\Path\Python\Sandbox_FTP_TLS_Explicit.py", line 12, in connect
    ftp.auth()
  File "C:\Path\Python\Python310\lib\ftplib.py", line 756, in auth
    self.sock = self.context.wrap_socket(self.sock, server_hostname=self.host)
  File "C:\Path\Python\Python310\lib\ssl.py", line 513, in wrap_socket
    return self.sslsocket_class._create(
  File "C:\Path\Python\Python310\lib\ssl.py", line 1071, in _create
    self.do_handshake()
  File "C:\Path\Python\Python310\lib\ssl.py", line 1342, in do_handshake
    self._sslobj.do_handshake()
ssl.SSLError: [SSL: SSLV3_ALERT_HANDSHAKE_FAILURE] sslv3 alert handshake failure (_ssl.c:997)

解决建议

从日志对比能看到,WinSCP用的是TLSv1协议和DHE-RSA-AES256-SHA加密套件,而Python 3.10默认的SSL上下文可能禁用了这些旧协议/套件,导致握手失败。试下面的配置:

  • 指定兼容的SSL协议和加密套件
    手动创建SSL上下文,启用TLSv1,并添加服务器支持的加密套件:

    from ftplib import FTP_TLS
    import ssl
    
    # 创建SSL上下文,启用TLSv1
    context = ssl.SSLContext(ssl.PROTOCOL_TLSv1)
    # 添加服务器支持的加密套件
    context.set_ciphers('DHE-RSA-AES256-SHA')
    
    ftp = FTP_TLS(context=context)
    ftp.debugging = 2
    ftp.connect('xxx.xxxx.xxx', 990)
    ftp.auth()  # 执行TLS握手
    ftp.login('username', 'password')
    ftp.prot_p()  # 设置数据连接保护
    
  • 调整连接流程
    注意prot_p()应该在login()之后调用,和WinSCP的流程一致(WinSCP是登录后执行PBSZ和PROT P)。

  • 临时关闭证书验证(测试用)
    如果服务器证书存在问题(比如自签名),WinSCP可能跳过了验证,你可以临时关闭证书验证测试(生产环境不建议):

    context.check_hostname = False
    context.verify_mode = ssl.CERT_NONE
    

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.25 16:22:17