认证机制与传输安全
提交邮件前必须先证明身份,SMTP 认证通过 AUTH 命令完成,机制由 EHLO 能力列表给出。PLAIN 与 LOGIN 只是 base64 编码(不是加密),因此必须跑在 TLS 通道里;CRAM-MD5 用挑战应答不直接传口令,但散列强度偏弱;现代服务普遍推荐 XOAUTH2,用 OAuth2 令牌代替长期口令。
基本信息
| 协议基础 | RFC 4954 定义 AUTH 扩展,机制名由服务端在 EHLO 中宣传 |
|---|---|
| 凭证传输 | PLAIN 与 LOGIN 为 base64 编码,等同明文,必须配合 TLS |
| 典型端口 | 587 提交端口要求先 STARTTLS 再 AUTH;465 为隐式 TLS |
| 常见失败码 | 535 认证失败、534 需要更强机制、504 机制不支持 |
机制对照
| 机制 | 传输形式 | 安全性 |
|---|---|---|
| PLAIN | base64(空字节+用户+空字节+口令) | 依赖 TLS,明文中等效裸传 |
| LOGIN | 用户名与口令分两步 base64 | 依赖 TLS |
| CRAM-MD5 | HMAC 挑战应答,不传口令 | 不泄露口令,散列强度偏弱 |
| XOAUTH2 | OAuth2 Bearer 令牌 | 现代服务推荐,可细粒度撤销 |
| EXTERNAL | 靠 TLS 客户端证书表明身份 | mTLS 场景 |
生成 PLAIN 凭据串
生成 PLAIN 凭据串
printf '\0user@example.com\0password' | base64 # 生成 AUTH PLAIN 后的凭据串
openssl s_client -starttls smtp -connect smtp.example.com:587 -crlf
# 连接后手工输入:EHLO 主机名 → STARTTLS 成功后再次 EHLO → AUTH PLAIN <凭据串>典型使用场景
- 排查 535 认证失败:确认是用授权码而非登录口令,并核对是否已 STARTTLS
- 自建发信系统选择认证方式:优先 XOAUTH2 或应用专用密码
- 验证服务端是否强制加密:586 与 587 的 AUTH 时机不同
- 审计客户端是否在明文通道发送凭据
base64 不是加密:抓包里一眼就能还原用户名与口令,所以认证必须只走 TLS 通道;收到服务端「必须加密后才能认证」的报错时应升级加密,而不是换成明文端口。
STARTTLS 之后必须重新发 EHLO:加密通道里的能力列表可能与明文阶段不同,老客户端只在升级前发一次 EHLO,会出现认证机制不可用的假故障。
用 OAuth2 接入时要处理令牌过期:刷新令牌需要重新获取访问令牌再重连认证,直接把过期令牌当口令复用会持续得到 535,日志里却看不出与令牌生命周期有关。