术语 · DKIM 检查

如何检查应用邮件的 DKIM?

可靠的 DKIM 检查要基于一封真实送达的邮件。读取 DKIM-Signature 邮件头,提取其签名域名(`d=`)和选择器(`s=`),查询位于 `<selector>._domainkey.<domain>` 的对应 DNS 密钥,并对已签名的邮件头和正文进行加密验证。然后查看可信收件方的 Authentication-Results。请把记录是否可用、签名验证、DMARC 对齐、收件服务器接收和收件箱送达作为彼此独立的结果。

把 DKIM 检查拆成四项独立测试

仅做一次 DNS 查询并不是完整的 DKIM 检查。第一,确认邮件包含 DKIM-Signature 字段,并确定要测试的是哪个签名。第二,获取并解析该签名所指向的公钥记录。第三,验证已签名的邮件头和规范化后的正文是否仍与加密签名匹配。第四,判断通过验证的签名域名是否与可见的 From 域名满足 DMARC 对齐。这几层回答的是不同的问题:已发布的记录可能根本没有被使用,邮件可能引用了不存在的选择器,内容被修改后签名可能失败,而加密验证通过的签名也可能与作者域名不对齐。请分别记录每项结果,而不是只展示一个绿色徽章。同时也要把传输状态和邮箱状态区分开:服务商受理、收件服务器接收和收件箱送达都不是 DKIM 验证结果。

从真实邮件上的签名入手

通过正常的应用发信路径,向一个受控的收件人发信,并获取原始邮件。对每个 DKIM-Signature 字段,记录 `d=` 签名域名、`s=` 选择器、`a=` 算法、`c=` 规范化模式、`h=` 已签名邮件头列表、`bh=` 正文哈希、`b=` 签名数据,以及存在时的时间戳。RFC 6376 定义了签名域名和选择器标签,并用它们来定位公钥。不要根据服务商控制台去猜选择器,也不要在没有选择器的情况下查询 `_domainkey`。一封邮件可能带有来自发件方、中间方或邮件列表系统的多个签名,因此请分别保留每个签名的结果。避免把生产邮件粘贴到公开的检查工具中:原始邮件头和正文可能暴露收件人、邮件标识符、路由细节、退订令牌和应用内容。请使用访问受限的存储,并在不需要完整内容时使用脱敏后的诊断副本。

查询确切的选择器和签名域名

根据签名按 `<selector>._domainkey.<signing-domain>` 构造 DNS 名称。如果邮件头包含 `s=app2026` 和 `d=notify.example.test`,就查询 `app2026._domainkey.notify.example.test` 的 TXT 记录。记录原始名称、解析器、响应、TTL 以及任何 CNAME 链。请解析返回的“标签=值”格式记录,而不是搜索某段文本片段。该记录可以声明版本、密钥类型、服务限制、标志、哈希算法和公钥数据。公钥值为空表示该密钥已被撤销。请区分 NXDOMAIN、空应答、内容格式错误、不支持的算法、不可用的密钥以及解析器的暂时性故障。记录变更后,请在 TTL 过期后通过独立的解析器再次查询,但不要假设所有收件方都已立即更新。DNS 查询成功只能证明当时返回了一条记录;它既不能证明被测邮件能通过验证,也不能证明服务商正在用该选择器为当前流量签名。

验证邮件头、正文哈希和签名

DKIM 验证遵循签名中声明的规范化规则。验证方先对正文进行规范化、计算哈希,并与 `bh=` 比较;再对 `h=` 中列出的已签名邮件头进行规范化,按规范纳入 DKIM-Signature 字段,并用公钥验证 `b=`。请使用持续维护的验证库或收件方可信的身份验证结果,而不是用字符串操作自行重现这些转换。正文哈希不匹配通常意味着正文在签名后被修改;而邮件头签名失败则可能说明已签名的邮件头被修改、密钥错误、签名数据损坏或实现有误。请记录是哪个阶段失败。检查 From、Subject、Date 和 Message-ID 等重要字段是否已被签名,但不要臆造一套通用的签名邮件头策略。规范化可以容忍规定范围内的格式变化,但并不能让任意插入页脚、改写 MIME、破坏换行符或传输过程中的修改变得安全。

在信任边界内读取收件方结果

RFC 8601 定义了 Authentication-Results 邮件头以及 DKIM 结果,包括 none、pass、fail、policy、neutral、temperror 和 permerror。pass 表示收件方找到了一个可接受且通过验证测试的签名。temperror 可能反映一种很可能会变化的情况,例如暂时性的密钥查询失败;而 permerror 表示在未修正问题的情况下,重试也不太可能成功。请记录报告结果的身份验证服务,以及提供时的签名域名、选择器和算法。只信任在收件系统文档所述边界内插入的结果,因为发件方可以在发送前添加伪造的 Authentication-Results 字段。请查看最终收件环境中最上方的可信结果,并考虑中间各跳的情况。如果不同收件方的结论不一致,请比较确切的邮件版本、DNS 视图、评估时间、支持的算法和本地策略。不要把 `dkim=pass` 解读为邮箱服务商认可了内容或把邮件放进了收件箱。

将 DMARC 对齐与 DKIM 通过分开检查

DKIM 通过验证的是 `d=` 中的签名域名;它并不要求该域名与可见的 RFC 5322 From 域名相同。RFC 9989 规定,只有当通过 DKIM 验证的标识符在适用的严格或宽松对齐模式下与作者域名对齐时,才会将其用于 DMARC。例如,一封来自 `billing.example.test`、以 `d=provider.test` 签名的邮件可以通过 DKIM,但仍然不对齐。来自 `d=example.test` 的有效签名在宽松模式下可能对齐,具体取决于组织域名的计算方式和策略。请报告三个字段:DKIM 结果、签名域名和对齐判定。当 DKIM 失败或不对齐时,邮件也可以通过对齐的 SPF 通过 DMARC,因此 DMARC 通过并不能证明某个特定的 DKIM 签名通过了验证。当前的 Gmail 发件人指南对相应流量提出了身份验证和对齐要求,但满足这些要求仍不能保证收件服务器接收或进入收件箱。

检查当前算法和密钥轮换

RFC 8301 更新了 DKIM 的加密要求:签名方必须使用 `rsa-sha256`,验证方必须支持它,并且不得使用 `rsa-sha1`。它还要求 RSA 签名密钥至少为 1024 位,同时解释了为什么在运维条件允许时更长的密钥更可取。检查工具应识别算法,并标记过时或不可用的密钥材料,但不应声称仅凭密钥长度就能让一个邮件流变得可信。各服务商的流程不尽相同。Amazon SES 的文档说明 Easy DKIM 默认使用 2048 位密钥,并提醒:如果在没有中间步骤的情况下更改签名方式,可能会出现一段邮件未经过 DKIM 签名的时期。请使用两个有效选择器或服务商文档中的重叠机制来规划轮换,确认新邮件已使用新选择器,在延迟邮件仍可能到达期间保留旧公钥,并在重叠期结束后再将其删除。切勿在 DNS、日志、工单或提示词中公开私有签名密钥。

从邮件本身向外排查故障

检查失败时,请在修改 DNS 之前先保存原始邮件和收件方结果。确认邮件确实是由预期的应用和服务商生成的。如果没有签名,请检查该身份、区域、租户或邮件类别是否启用了签名。如果选择器查询失败,请比对确切的 `d=` 和 `s=` 值、DNS 区域、CNAME 目标、TTL 以及最近的轮换。如果密钥能解析但正文哈希失败,请检查网关、邮件列表页脚、跟踪链接改写、MIME 转换、换行符,以及可能在签名后修改内容的安全产品。如果正文哈希匹配但加密签名失败,请检查已签名邮件头的变化、密钥不匹配和签名实现。如果 DKIM 通过但 DMARC 失败,请测试对齐,而不是重新发布同一个密钥。在相关 TTL 或配置传播完成后,通过受控收件人重新测试,并为每个邮件类别记录证据,而不是凭一个成功的样本就宣布整个域名已修复。

保留可审计的 DKIM 检查记录

对于每一封受控邮件,请保留一个不含敏感信息的关联标识符、发信系统、服务商账户或工作区、可见的 From 域名、收件系统、邮件时间,以及每个签名的完整结果。记录内容包括 `d=`、`s=`、`a=`、规范化方式、已签名邮件头、DNS 查询名称、DNS 响应时间和 TTL、密钥记录状态、正文哈希结果、签名结果、可信的 Authentication-Results 值、DMARC 对齐判定以及修复负责人。只在访问和保留管控合适的地方存储原始邮件。注明测试场景:正常应用发信、服务商迁移、密钥轮换、网关路径或转发场景。这样可以让回归问题具有可比性,并避免在选择器或邮件处理方式变化之后,一张截图仍被当作永久证据。在服务商设置、DNS、签名方式或路由发生变化,或新增邮件类别之后,请重新检查。运维仪表板应明确显示“未知”和“不可用”状态,而不是悄悄把它们当作通过或失败。

了解 SendHQ 在检查中的作用

SendHQ 要求已验证的 From 域名,并提供投递事件。进行 DKIM 检查时,请通过预期的应用路径发送受控邮件,检查收到的签名,查询实际的 `d=` 和 `s=` 值,并单独记录对齐。不要仅凭产品文档推断选择器、密钥长度、签名算法、收件箱送达率或投递保证。

常见问题

在哪里找到 DKIM 选择器?

打开原始邮件,找到 DKIM-Signature 字段。选择器是 `s=` 的值,签名域名是 `d=` 的值。用两者拼出 `<selector>._domainkey.<signing-domain>` 进行 DNS 查询。

找到了 DKIM DNS 记录,是否就代表 DKIM 通过?

不代表。该记录只提供密钥材料和策略标签。验证方必须用它来检查具体那封邮件经过规范化的正文、已签名的邮件头、正文哈希、签名数据和算法。请用一封真实送达的邮件进行测试。

DKIM 通过的同时 DMARC 会失败吗?

会。DKIM 可以使用一个与可见 From 域名不对齐的签名域名通过验证。DMARC 要求在适用的对齐模式下有一个通过且对齐的 SPF 或 DKIM 标识符,因此请分别报告验证结果和对齐结果。

DKIM 正文哈希不匹配的原因是什么?

验证方收到的规范化正文与签名方计算哈希时的正文不一致。常见的排查方向包括签名之后的网关、页脚、跟踪链接改写、MIME 转换、安全工具和换行符变化。诊断前请先保存原封不动的邮件。

轮换后应立即删除旧的 DKIM 选择器吗?

不应该。请在受控的过渡期内保留旧公钥,这样用旧密钥签名的延迟邮件仍能通过验证。在删除旧的 DNS 记录之前,请确认新流量已在使用新选择器,并遵循服务商文档中的轮换流程。

DKIM 通过能证明邮件进入收件箱吗?

不能。它只证明在进行评估的收件方处,被测邮件带有一个可接受的签名。收件方在接收邮件和对邮件分类时,仍会综合考虑身份验证对齐、信誉、内容、投诉、收件人和本地策略等信号。

参考来源