
CUSTOMIZE 当我们谈到“Email Authentication”时,我们指的是一种技术,这种技术为消息的接收者提供了一定程度的确定性,确保消息实际上是来自消息声称的来源。
当我们谈到“Email Authentication”时,我们指的是一种技术,它为消息的接收者提供了一定程度的确定性,即消息实际上是来自声称的消息来源。这种技术背后的想法是达到某种程度上的防御,以防止欺诈性电子邮件,如网络钓鱼和欺骗邮件,这些邮件可能会削弱收件人对接收电子邮件的信任。不过,发送经过认证的电子邮件这一行为并不表明电子邮件是好的或需要的;这仅意味着可以可靠地建立和使用已认证方的声誉,以便在电子邮件的接受和放置决策中。
目前有两种形式的电子邮件认证:
发送者政策框架 (SPF)
域名密钥识别邮件 (DKIM)
在今天的帖子中,我将介绍什么是DKIM及其工作原理。
DKIM 概览
与其身份验证对应的 SPF 不同,SPF 提供了一种方法让域授权主机代表其发送邮件,DKIM 提供了一种方法,使实体(域、组织、个人等)能够对消息负责,而与实际发送消息的实体无关。虽然在许多情况下,负责实体和发送实体会是相同的,或至少是密切相关的,但在 DKIM 中,并不要求必须如此。
我希望通过这篇文章,你能够学习并理解以下关于 DKIM 的概念:
DKIM 是一种“基于内容”的身份验证,不同于“基于路径”的 SPF。
负责实体通过在消息头中插入一对加密哈希来“签署”消息,以此申明其责任。
DKIM 验证由接收域尝试生成相同的两个哈希来完成。
在许多情况下,DKIM 验证在发送服务器传输完整消息之前无法完成。
验证失败可能难以排查。
“Content-Based” Authentication
DKIM Signing 和 Validation
希望进行DKIM签名邮件的组织将首先生成两个加密密钥。其中一个密钥保持私密,并可供发送服务器用于邮件的签名,另一个则公开在DNS中,供接收域尝试验证签名。生成这些密钥和安装它们的方法依赖于平台,超出了本文的范围,虽然稍后我将描述在DNS中发布公用DKIM密钥。
DKIM-Signature 标头
为了开始我们对DKIM的理解,让我们先看看一个DKIM签名头:
DKIM-Signature: v=1; a=rsa-sha256; d=welcome.foo.com; s=notices; c=relaxed/relaxed; q=dns/txt; i=@welcome.foo.com; t=1454417737; h=From:Reply-To:Subject:Date:Message-ID:To:MIME-Version:Content-Type; bh=e+6RkdhJe69wcQKtRKw9rpDgkkPPbZ8Xwj/2Hi243Sc=; b=KhK4OjejS4QEBr1RwL/naZKBNLoFnR/3lmDOWZC3av4c2aH5Yg/D4vqhh1CpcyfP vRm7cp5EvrnPEsOA7r3E15jarzNFNHXtwjxCFn4g8StsXFOio9vHkO7bmp6t2aLu 8bPkX6cNHgULYS6TdqYd65y5xCDMEaQ9a3mnhF2TQss=;
DKIM签名头是一系列键值对,有些对读者更感兴趣,而其他的则不太重要,但我将在此描述它们。
首先,我们来看一下对读者来说大多只是顺便了解的部分:
v=1; – 指定DKIM版本(1是唯一有效的值)
a=rsa-sha256; – 用于构建加密哈希的算法
c=relaxed/relaxed; – 关于在创建DKIM签名时去除头部和主体中的空白有两套规则;这些规则称为“规范化规则”(因此键为c),规则集可以是“relaxed”或“strict”。
t=1454417737; – 签名创建的时间戳。
这三个头部分包含实际的签名信息:
bh=e+6RkdhJe69wcQKtRKw9rpDgkkPPbZ8Xwj/2Hi243Sc=; – 这是邮件主体的哈希。
h=From:Reply-To:Subject:Date:Message-ID:To:MIME-Version:Content-Type; – 这是用于创建下面显示的签名数据的头部列表。
b=KhK4OjejS4QEBr1RwL/naZKBNLoFnR/3lmDOWZC3av4c2aH5Yg/D4vqhh1CpcyfPvRm7cp5EvrnPEsOA7r3E15jarzNFNHXtwjxCFn4g8StsXFOio9vHkO7bmp6t2aLu8bPkX6cNHgULYS6TdqYd65y5xCDMEaQ9a3mnhF2TQss=; – 这是实际的DKIM签名数据
这三个部分是接收服务器在验证签名时最感兴趣的:
d=welcome.foo.com; – 这标识了签署邮件的域
s=notices; – 选择器;域可以有多个用于签署邮件的选择器。
i=@welcome.foo.com; – 这是代表谁签署邮件的身份。语法上看起来像一个电子邮件地址,甚至可能是一个;电子邮件地址的本地部分可以为空,如此例所示,而域部分必须与签名中的d=部分的域相同或为其子域。
这些部分对接收服务器感兴趣的原因是它们提供了帮助接收方验证签名所需的信息。
DKIM Validation
除了要求i=域必须与d=域相同或是d=域的子域外,验证器还使用d=和s=位来查找DNS中的签名者的公用DKIM密钥。该密钥是DNS中的TXT记录,它总是位于selector._domainkey.domain的位置。因此,在我们的示例中,使用s=notices和d=welcome.foo.com,公用DKIM密钥将位于DNS中的notices._domainkey.welcome.foo.com,并且它可能看起来像这样:
notices._domainkey.welcome.foo.com. 描述性文本 "v=DKIM1\; h=sha256\; p=MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDlXNDEHOstbxTkS0tjqy9qw2J 1mnjW5FBWQ4dyrYfrkr8/9VrtAY+eWcKMLUcR3mGFpk9QeHCXoILMJ22TmP1JfhzN NoCcMLffy39eWZKmtm4/Ry29qWBFvn2LKl5W3BBC3e4wQ14l+CQqY4C0QifIrPBwR pod8n+//qIpQIDAQAB\; s=email"
验证器使用该密钥(p=位)来产生消息的哈希集;如果这些哈希匹配,则表示消息在传输过程中未被更改,因此该消息可以为消息签名者的声誉作出贡献,并可能从中受益。
验证失败和故障排除
我先前提到,DKIM 失败可能难以排除故障,我将在这里解释原因。
一些 DKIM 验证失败有明显原因,例如邮件未被签署,或者签署域的公钥没有在 DNS 中找到或语法不正确,或者邮件在传输中显然被篡改。当这些类型的失败发生时,很容易找出问题并建议解决方案。然而,更棘手的是那些导致最令人沮丧的支持体验的情况,即邮件已签署,公钥存在于 DNS 中,邮件明显未被篡改,但验证报告签名验证失败。
这些问题难以排除故障的原因是因为任何一方都没有真正的方法来重现邮件签署和验证时的条件。邮件在其 DKIM-Signature 头部包含了签署者在签署时生成的哈希值,但验证者可能无法访问签署者的基础设施,因此无法尝试在签署者的条件下重现签名。同样,签署者可能无法访问验证者的基础设施,因此无法以验证者的方式进行消息验证。
我所描述的这种失败是罕见的,而 DKIM 验证失败本身通常不会对邮件投递位置产生影响。根据我的经验,这种失败比任何其他类型的 DKIM 问题都引发更多的支持请求。