ssl - smtplib.SMTP starttls 失败并出现 tlsv1 警报解码错误

标签 ssl smtp openssl smtplib python-3.4

我今天遇到了以下奇怪的行为。

以下代码适用于 Python 3.3:

smtp = smtplib.SMTP()
smtp.connect(host="smtp.gmail.com", port=587)
smtp.ehlo()
smtp.starttls()

在 Python 3.4 中,上述代码不起作用,而是遇到以下错误:

   File "smtp_test.py", line 10, in <module>
    smtp.starttls()
   File "/usr/lib/python3.4/smtplib.py", line 676, in starttls
    server_hostname=server_hostname)
   File "/usr/lib/python3.4/ssl.py", line 344, in wrap_socket
    _context=self)
   File "/usr/lib/python3.4/ssl.py", line 540, in __init__
    self.do_handshake()
   File "/usr/lib/python3.4/ssl.py", line 767, in do_handshake
    self._sslobj.do_handshake()
   ssl.SSLError: [SSL: TLSV1_ALERT_DECODE_ERROR] tlsv1 alert decode error (_ssl.c:598)

如果将上面的代码修改为在构造函数中指定主机和端口并且不使用 connect 方法,如下面的代码所示,那么它可以工作。

smtp = smtplib.SMTP(host="smtp.gmail.com", port=587)
smtp.ehlo()
smtp.starttls()

上述行为发生在 OpenSSL 版本 1.0.1f 和 OpenSSL 1.0.1g 中

有人可以向我解释一下这种行为吗?

最佳答案

根据 tcpdump,3.4 中的代码发送带有空目标名称的 SNI 扩展。当同一 IP 地址后面有不同的证书时,将使用 SNI(服务器名称指示)。我认为这是一个错误:如果它没有名称,则不应发送 SNI 扩展,而应发送其中包含零长度名称的扩展。

关于ssl - smtplib.SMTP starttls 失败并出现 tlsv1 警报解码错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23616803/

相关文章:

ssl - Asp.netSendEmail SMTP 服务器要求安全连接或客户端未通过身份验证

macos - 无法在 MacOS High Sierra (10.13.3) 上安装 Plone 5.0.8

带有 SMTP 后端的 django send_mail 无法发送电子邮件

windows - 如何在 Windows 上使用 OpenSSL FIPS 静态库构建 DLL?

c++ - 调用 fork() 后 SSL_accept 挂起

C# Web API - 通过客户端证书对用户进行身份验证

amazon-web-services - Amazon EC2 上的 HTTPS 证书

MYSQL远程连接需要SSL

docker - Traefik 自签名证书

delphi - 如何将 SMTP Amazon SES 与 Delphi 结合使用?