邮件安全之DKIM
0x1: DKIM是邮件发件人身份验证技术实现方式之一,数字签名在其中的应用同时保证了发件人身份可靠以及邮件内容的完整,用于防护发件人欺诈,是拦截垃圾邮件及钓鱼邮件的有效手段。
我们先来看一个DKIM签名,如下:
DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=<sender domain>;
s=selector1;
h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck;
bh=0yxAGQYAXZRrgDxuKKJ/yZaxG5v3IDluFDDN4tzAZFM=;
b=OYCVOTGgcZlZwAWYtmUsWIGev+zMqVCE0mVuqVQvhWfxwcG7W7tcdq5ObEPYvZTf2W8PK8U9bMI2QAnA9fB9lfqW/ndfy00k5lGJk6igZlyH2Hr3FC+A/8EcYBifWdqz2AbTVDo8uwHYVK5RZjgHPohzypyDsR+o4f1qXqLfjYc=
签名中各标签的含义,这里不作解释。我们将在这篇文章里通过手动验证这个数字签名来了解DKIM签名验证过程。
0x2: 执行DKIM的手动验证,关键点是对邮件正文及信头的规范化(Canonicalization)。relaxed/relaxed是广泛使用的处理方式,允许邮件服务器对邮件内容的少量变更,比如插入空行等。
The "simple" Header Canonicalization Algorithm
‘Simple’方式的邮件信头的规范化处理不对信头做任何修改,保留原始信头原。但是需按照DKIM签名里的h标签值中信头列表的顺序排列信头。
The "relaxed" Header Canonicalization Algorithm
‘Relaxed’方式的信头规范化处理需要按下面列出的要求进行:
a. 将所有header name转换为小写字母书写。
b. 分行(folding,参考RFC5322)处理的信头需要删除多余的CRLF,恢复为一行,保留行末尾的CRLF。
c. 将连续的空白字符(包括空格、制表符TAB)转换为单个空格字符。
d. 删除header value末尾的空白符。
e. Header name和value是由冒号分隔,需删除冒号前后的空格
f. 需按照DKIM签名里的h标签值中信头列表的顺序排列信头。
The "simple" Body Canonicalization Algorithm
‘Simple’方式的邮件信体的规范化处理的要点为:
a. 删除空白行
b. 删除信体末尾多余的换行符CRLF,仅保留一个。
The "relaxed" Body Canonicalization Algorithm
‘Relaxed’方式的邮件信体的规范化处理的要点为:
a. 删除每行末尾的空白字符。需保留换行符。
b. 每行中连续的空字符转换为单个空格符。
c. 删除信体末尾的空白行,需保留一个CRLF.
首先验证邮件正文的hash值是否匹配
将邮件正文按照DKIM签名里指定的规范化处理方式处理后,按SHA256方式计算正文的hash值并将Hex格式的结果转换为base64.
验证正文hash值匹配后,执行签名的验证,分两步进行:
Step 1:
从邮件DKIM签名中提取b标签的值,如下:
‘OYCVOTGgcZlZwAWYtmUsWIGev+zMqVCE0mVuqVQvhWfxwcG7W7tcdq5ObEPYvZTf2W8PK8U9bMI2QAnA9fB9lfqW/ndfy00k5lGJk6igZlyH2Hr3FC+A’
这是base64格式的数据,需转换为原始数据,并保存到文件hash.dat.
通过DNS查询,获取该数字签名对应的公钥'Public Key',保存到文件domain.pem.
使用openssl工具来验证数字签名,
openssl rsautl -verify -inkey domain.pem -pubin -in hash.dat -asn1parse
验证结果是SHA256的哈希值,如下:
哈希值为:'5ea108c3a6c1fd5283d7ebc9ec8625352b1ac58542745e0c45490fbb063c5449'
Step 2:
规范化处理邮件信头,需将DKIM签名信头规范化处理后放置在指定信头后面。
将处理后的信头提交进行SHA256计算,得到哈希值:
'5ea108c3a6c1fd5283d7ebc9ec8625352b1ac58542745e0c45490fbb063c5449'
该哈希值和Step 1中验证计算得到的哈希值相同,即通过DKIM验证。
由于验证需要使用指定域名的公钥,从而可以验证发件人身份可靠。邮件正文的哈希值加入了标签b的验证,可以保证数据的完整,没有被篡改。
总结
- 上一篇: 答云淡风轻:汉化Rails报错信息,部署
- 下一篇: ShowWindow函数用法。