← RFC Reference

DKIM — 域名密钥识别邮件

Internet Standard Email Authentication Published March 2026
ELI5: 将 DKIM 想象成信件上防篡改的封蜡。发送前,邮件服务器用唯一的封印(密码签名)对邮件进行标记。邮件送达时,收件人可以根据发布在 DNS 中的公钥检查封印。如果封印完好无损,说明邮件在传输中未被篡改,确实来自拥有该域名私钥访问权限的人。

为什么存在这个RFC

SPF验证消息来自授权IP地址,但不涉及消息内容。消息可能通过SPF,然后被受损的中继修改。当邮件被转发时SPF也会失效,因为发送IP会改变。

DKIM解决了这两个问题。通过将加密签名附加到消息本身,它提供了域级身份断言,能够存活转发(签名随消息传输)并保证内容完整性(任何修改都会使签名失效)。

2011年发布的RFC 6376是当前DKIM规范。它过时了RFC 4871并引入了规范化、密钥管理和签名语义的改进。它仍然是现代电子邮件认证的基础,与SPF和DMARC并行。

工作原理

签名(发送方)

  1. 发送邮件服务器(或上游签名代理)选择要签名的头部和主体。
  2. 它使用simple或relaxed算法规范化所选内容,以标准化空格和大小写。
  3. 它计算规范化主体的哈希,然后计算所选头部加上主体哈希的哈希。
  4. 它使用域的私钥(RSA或Ed25519)对头部哈希进行签名。
  5. 它向消息添加DKIM-Signature头部,包含签名、签名域(d=)、选择器(s=)和关于签名内容的元数据。

验证(接收方)

  1. 接收者从DKIM-Signature头部提取d=(域)和s=(选择器)值。
  2. 它在<selector>._domainkey.<domain>处查询DNS以获取公钥。
  3. 它使用签名中指定的相同算法重新规范化已签名的头部和主体。
  4. 它针对公钥验证签名。如果有效,结果为pass。

DKIM-Signature头部示例

DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=example.com; s=mtg20240101; h=from:to:subject:date:message-id:mime-version:content-type; bh=2jUSOH9NhtVGCQWNr9BrIAPreKQjO6Sn7XIkfJVOzv8=; b=LjIEJLNOTAREALSIGh8gAiGVQOr3K7...截断...

DNS公钥记录

mtg20240101._domainkey.example.com. IN TXT "v=DKIM1; k=rsa; p=MIGfMA0GCSqGSIb3DQEB...截断..."

关键技术细节

规范化

电子邮件在传输中可能会被微妙地修改(尾随空格被删除、头部被重新折叠)。规范化在哈希前对内容进行标准化,使得无害的改动不会破坏签名。有两种可用的算法,分别为头部和主体指定:

算法 头部 主体
simple 除了头部值的尾随空格外无更改 除了尾随空行外无更改
relaxed 小写头部名称、展开行、压缩空格 压缩空格、删除每行尾随空格

最常见的设置是c=relaxed/relaxed,它容忍最常见的传输中修改。

密钥类型

RFC 6376定义了RSA签名。RFC 8463后来添加了Ed25519支持。RSA密钥应至少2048位;1024位密钥被认为很弱,会被某些接收者拒绝。Ed25519密钥更小(DNS中44个字符)且验证速度更快。

选择器

选择器(s=标记)允许域同时发布多个DKIM密钥。这对密钥轮换至关重要:在新选择器下发布新密钥、开始用它签名,然后在过渡期后删除旧选择器的DNS记录。

l=标记(主体长度限制)

可选的l=标记限制有多少字节的主体被签名。这本意是允许邮件列表附加页脚而不破坏签名。实际上,它造成了安全漏洞:攻击者可以在已签名的部分之后附加恶意内容。大多数安全意识强的实现避免使用l=。

头部签名

h=标记列出签名中包含的头部。最佳实践是至少签名:From、To、Subject、Date、Message-ID、MIME-Version和Content-Type。规范要求From头部。签名不存在的头部可防止其在签名后被添加(重要的反重放措施)。

常见错误

递送能力影响

Related RFCs