小编use*_*068的帖子

使用STARTTLS从Python发送电子邮件

我想使用Python的smtplib发送带有Python脚本的电子邮件.

如果可以建立与服务器的加密连接,则脚本应仅发送电子邮件.要加密到端口587的连接,我想使用STARTTLS.

使用一些例子我写了以下代码:

smtp_server = smtplib.SMTP(host, port=port)
context = ssl.create_default_context()    
smtp_server.starttls(context)
smtp_server.login(user, password)
smtp_server.send_message(msg)
Run Code Online (Sandbox Code Playgroud)

msg,host,port,user,password是我脚本中的变量.我有两个问题:

  • 连接是否始终加密或是否容易受到STRIPTLS攻击(https://en.wikipedia.org/wiki/STARTTLS).
  • 我应该使用SMTP对象的ehlo()方法吗?在某些示例中,在调用starttls()之前和之后显式调用它.另一方面,在smptlib的文档中写道,如果有必要,sendmail()将调用它.

[编辑]

@tintin解释说,这ssl.create_default_context()可能导致不安全的联系.因此,我通过以下方式使用一些示例更改了代码:

_DEFAULT_CIPHERS = (
'ECDH+AESGCM:DH+AESGCM:ECDH+AES256:DH+AES256:ECDH+AES128:DH+AES:ECDH+HIGH:'
'DH+HIGH:ECDH+3DES:DH+3DES:RSA+AESGCM:RSA+AES:RSA+HIGH:RSA+3DES:!aNULL:'
'!eNULL:!MD5')

smtp_server = smtplib.SMTP(host, port=port)

# only TLSv1 or higher
context = ssl.SSLContext(ssl.PROTOCOL_SSLv23)
context.options |= ssl.OP_NO_SSLv2
context.options |= ssl.OP_NO_SSLv3

context.set_ciphers(_DEFAULT_CIPHERS)
context.set_default_verify_paths()
context.verify_mode = ssl.CERT_REQUIRED

if smtp_server.starttls(context=context)[0] != 220:
    return False # cancel if connection is not encrypted
smtp_server.login(user, password)
Run Code Online (Sandbox Code Playgroud)

对于密码设置,我使用了最近版本的一些代码ssl.create_default_context().这些设置是否合适?

注意:在原始问题的代码中是一个错误.以下是相关行的正确版本:

smtp_server.starttls(context=context)
Run Code Online (Sandbox Code Playgroud)

[\编辑]

python email encryption smtplib starttls

3
推荐指数
1
解决办法
2万
查看次数

标签 统计

email ×1

encryption ×1

python ×1

smtplib ×1

starttls ×1