python - 如何通过 smtplib (TLS) 接受来自电子邮件服务器的自签名证书?

标签 python python-2.7 ssl smtplib starttls

我的脚本

from stmplib import SMTP
con = SMTP(server, port)
con.starttls()
con.login(user, pass)
con.quit()

报错: python2.7/ssl.py",第 847 行,在 do_handshake self._sslobj.do_handshake() 中

当我对此服务器运行命令 openssl 时,出现错误 21:Verify return code: 21 (unable to verify the first certificate)

我想知道如何在 smtplib 的 python 选项中指定“当通过 tls 建立连接到电子邮件服务器时始终接受自签名证书”? 就像我在 requests.get 设置键 verify=False 中所做的那样。

更新 这个带有自定义 smtp 类和 context = ssl._create_unverified_context() 的变体返回与上面相同的错误:

import smtplib
import ssl

class MySMTP(smtplib.SMTP):
    def __init__(self, host='', port=0, timeout=5):
        smtplib.SMTP.__init__(self, host, port, timeout=timeout)
        self._host = host

    def starttls(self, keyfile=None, certfile=None, context=None):
        from urllib import _have_ssl

        self.ehlo_or_helo_if_needed()
        if not self.has_extn("starttls"):
            raise SMTPNotSupportedError("STARTTLS extension not supported by server.")
        (resp, reply) = self.docmd("STARTTLS")
        if resp == 220:
            if not _have_ssl:
                raise RuntimeError("No SSL support included in this Python")
            if context is not None and keyfile is not None:
                raise ValueError("context and keyfile arguments are mutually "
                             "exclusive")
            if context is not None and certfile is not None:
                raise ValueError("context and certfile arguments are mutually "
                             "exclusive")
            if context is None:
                context = ssl._create_stdlib_context(certfile=certfile,
                                                 keyfile=keyfile)
            self.sock = context.wrap_socket(self.sock,
                                        server_hostname=self._host)
            self.file = None
            # RFC 3207:
            # The client MUST discard any knowledge obtained from
            # the server, such as the list of SMTP service extensions,
            # which was not obtained from the TLS negotiation itself.
            self.helo_resp = None
            self.ehlo_resp = None
            self.esmtp_features = {}
            self.does_esmtp = 0
        return (resp, reply)

con= MySMTP(server, port)
context  = ssl._create_unverified_context()
con.starttls(context = context)
con.login(user, pass)
con.quit()

最佳答案

迟到的答案,但我修复了 ssl.SSLError: [SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed (_ssl.c:852) on python 3.7 使用 ssl._create_unverified_context(),即:

import smtplib, ssl
context = ssl._create_unverified_context()
with smtplib.SMTP_SSL("domain.tld", 465, context=context) as server:
    server.login(user, password)
    server.sendmail(sender_email, receiver_email, message.as_string())

关于python - 如何通过 smtplib (TLS) 接受来自电子邮件服务器的自签名证书?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54976051/

相关文章:

python - 为什么 PyPy 没有包含在标准 Python 中?

python - 如何确保 Qt 表格单元格中的所有数据都可见?

python - 为什么 mysql 在与 python 一起使用时返回格式为 ('abc' ) 的字符串

python - 抓取时获取错误实例方法没有属性 '__getitem__'

python - 从 url 加载压缩 (.gz) .csv 文件时出现问题

python - 从印度专利网站上抓取专利数据

python - pika向rabbitmq发送消息超时

linux - CHECK_NRPE : Error - Could not complete SSL handshake

ssl - 如何为 IIS 6 创建自签名通配符 SSL 证书?

asp.net - IHTTPModule 在 ASP.NET 中在 HTTP 和 HTTPS 之间切换