← RFC Reference

RFC 8314:明文已过时

Standards Track Transport Security Published March 2026
ELI5: 多年来,电子邮件客户端通过明文端口连接到服务器,然后被要求"升级"到加密(STARTTLS)。这就像在拥挤的房间里用扬声器开始通话,然后低声说"让我们切换到私密线路"。RFC 8314 说:直接从私密线路开始。从第一个字节就用 TLS 连接——没有升级步骤,没有被窃听的窗口。

存在的原因

电子邮件历来使用三个明文端口进行客户端到服务器的通信:

端口 协议 用途
25 SMTP 服务器间中继
143 IMAP 邮箱访问
110 POP3 邮箱访问
587 投递 客户端消息投递

这四个端口都以明文连接开始。STARTTLS被后来添加以在中间流升级这些连接为TLS。但STARTTLS存在系统性弱点:

RFC 8314宣布这些明文连接对于电子邮件投递和邮箱访问已过时,并规定隐式TLS作为替代。

工作原理

隐式TLS对比STARTTLS

STARTTLS(旧方式):在明文端口连接,以明文交换问候,发送STARTTLS命令,协商TLS,然后继续加密会话。

-- 投递端口587上的STARTTLS --
220 mail.example.com ESMTP          ← 明文问候
EHLO client.example.com             ← 明文
250-mail.example.com                ← 明文
250-STARTTLS                        ← 攻击者可以删除此行
250 OK
STARTTLS                            ← 明文
220 Go ahead                        ← 明文
-- TLS握手在此处发生 --
EHLO client.example.com             ← 现已加密
AUTH PLAIN dXNlcjpwYXNz            ← 加密(安全)

隐式TLS(RFC 8314方式):连接到专用TLS端口。TLS握手是连接时发生的第一件事。完全没有明文阶段。

-- 投递端口465上的隐式TLS --
-- TLS握手在连接时立即发生 --
220 mail.example.com ESMTP          ← 从第一个字节加密
EHLO client.example.com             ← 加密
AUTH PLAIN dXNlcjpwYXNz            ← 加密

新端口分配

服务 旧版(STARTTLS) 新版(隐式TLS) IANA名称
消息投递 587 465 submissions
IMAP 143 993 imaps
POP3 110 995 pop3s

端口465有复杂的历史。它最初在1990年代后期被分配给"SMTPS",后来被撤销以支持端口587上的STARTTLS。RFC 8314将其重新分配为submissions(注意有's')用于隐式TLS投递。这一次是官方且永久的。

端口25呢?

端口25用于服务器间中继,不是客户端投递。RFC 8314不改变端口25行为。服务器间SMTP仍使用机会性STARTTLS,由MTA-STS或DANE提供强制。区分很重要:客户端使用凭据认证(必须受保护),而服务器通过DNS、DKIM和SPF认证。

关键技术细节

TLS版本要求

RFC 8314要求TLS 1.2或更高版本。TLS 1.0和1.1已由RFC 8996弃用。实际上,你应该要求最低TLS 1.2并倾向于TLS 1.3。

证书验证

使用隐式TLS,客户端必须使用标准Web PKI规则针对预期的主机名验证服务器证书。这与STARTTLS时代许多客户端接受任何证书的情况有重大改变。证书必须:

用于服务发现的SRV记录

RFC 8314与RFC 6186配合通过SRV记录进行自动客户端配置:

; 隐式TLS投递(RFC 8314 + RFC 6186) _submissions._tcp.example.com. IN SRV 0 1 465 mail.example.com. ; 隐式TLS IMAP _imaps._tcp.example.com. IN SRV 0 1 993 mail.example.com. ; 隐式TLS POP3 _pop3s._tcp.example.com. IN SRV 0 1 995 mail.example.com.

客户端配置

对于集成SMTP投递的应用开发者:

# Python示例:端口465上的隐式TLS
import smtplib

# 正确:SMTP_SSL立即以TLS连接
with smtplib.SMTP_SSL('mail.example.com', 465) as smtp:
    smtp.login('user', 'password')
    smtp.send_message(msg)

# 避免:端口587上的STARTTLS(遗留)
# with smtplib.SMTP('mail.example.com', 587) as smtp:
#     smtp.starttls()
#     smtp.login('user', 'password')

常见错误

可递送性影响

Related RFCs