DNS安全扩展(DNSSEC)引入了4种新
的DNS资源记录类型:DNS公钥(DNSKEY)、资源记录签名(RRSIG)、Next Secure (NSEC)和委托签名者(DS)。本文档定义了每个资源记录(RR)、RR的RDATA格式及其表示格式(ASCII表示)的用途。
这个文档是定义DNSSEC的文档系列的一部分,应该作为一个集合一起阅读。
[RFC4033]包含对DNSSEC的介绍和常用术语的定义;读者应该熟悉这份文件。[RFC4033]还包含由本文档集更新和废止的其他文档列表。
[RFC4035]定义了DNSSEC协议操作。
读者还应该熟悉[RFC1034]、[RFC1035]中描述的基本DNS概念,以及随后更新它们的文档,特别是[RFC2181]和[RFC2308]。
本文档定义了DNSSEC资源记录。本文档中给出的所有数字DNS类型代码都是十进制整数。
本文件中“必须”、“不得”、“必须”、“必须”、“不得”、“应当”、“不应当”、“建议”、“可以”、“可选”等关键词的解释见[RFC2119]。
DNSSEC使用公钥加密对DNS资源记录集(RRset
)进行签名和身份验证。公钥存储
在DNSKEY资源记录中,并用于[RFC4035]中描述的DNSSEC身份验证过程:区域使用私钥签署其权威RRset,并将相应的公钥存储在DNSKEY RR中。然后,解析器可以使用公钥验证区域中覆盖rrset的签名,从而对它们进行身份验证。
DNSKEY RR不是用来存储任意公钥的记录,也不能用来存储与DNS基础设施没有直接关系的证书或公钥。
DNSKEY RR类型的是48。
DNSKEY RR与class无关。
DNSKEY RR没有特殊的TTL要求。
DNSKEY RR的RDATA由2个八字节标记字段、1个八字节协议字段、1个八字节算法字段和公钥字段组成。
1 1 1 1 1 1 1 1 1 1 2 2 2 2 2 2 2 2 2 2 3 3
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Flags | Protocol | Algorithm |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
/ /
/ Public Key /
/ /
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
flag字段的第7位是区域key tag。如果第7位为1,那么DNSKEY记录就有一个DNS区域key,而DNSKEY RR的所有者名称必须是一个区域的名称。如果第7位为0,那么DNSKEY记录就会保留其他类型的DNS公钥,不能用来验证该值的RRSIGs。
Flags字段的第15位是安全入口点标志,在[RFC3757]中有描述。如果第15位的值为1,那么DNSKEY记录持有一个密钥,该密钥将用作安全入口点。此标志仅为区域签名或调试软件使用此DNSKEY记录的提示;在签名验证过程中,验证器不能根据这个位的设置以任何方式改变它们的行为。这也意味着带有SEP位集的DNSKEY RR也需要设置区域密钥标志,以便能够合法地生成签名。带有SEP设置和未设置区域密钥标志的DNSKEY RR不能用于验证覆盖rrset的RRSIGs。
0-6位和8-14位被保留:这些位在创建DNSKEY RR时值必须为0,在接收时必须被忽略。
协议字段必须为3,如果在签名验证期间发现DNSKEY RR是3以外的值,则必须将其视为无效。
算法字段标识公钥的加密算法,并确定公钥字段的格式。DNSSEC算法类型的列表可以在附录A.1中找到
公钥字段包含公钥材料。格式取决于存储密钥的算法,并在单独的文档中进行描述。
尽管Protocol字段的值始终为3,但保留它是为了向后兼容密钥记录的早期版本。
RDATA部分的表示格式如下:
标记字段必须表示为无符号的十进制整数。给定当前定义的标志,可能的值是:0、256和257。
协议字段必须表示为值为3的无符号十进制整数。
算法字段必须表示为无符号十进制整数,或者表示为附录A.1中指定的算法助记符。
公钥字段必须表示为公钥的Base64编码。Base64文本中允许有空格。有关Base64编码的定义,请参见[RFC3548]。
下面的DNSKEY RR存储example.com的DNS区域key。
example.com. 86400 IN DNSKEY 256 3 5 ( AQPSKmynfzW4kyBv015MUG2DeIQ3
Cbl+BBZH4b/0PY1kxkmvHjcZc8no
kfzj31GajIQKY+5CptLr3buXA10h
WqTkF7H6RfoRqXQeogmMHfpftf6z
Mv1LyBUgia7za6ZEzOJBOztyvhjL
742iU/TpPSEDhm2SNKLijfUppn1U
aNvv4w== )
前四个文本字段指定所有者名称、TTL、类和RR类型(DNSKEY)。值256表示Flags字段中的区域键位(第7位)的值为1。值3是固定的协议值。值5表示公钥算法。附录A.1将算法类型5标识为RSA/SHA1,并指出RSA/SHA1公钥字段的格式定义在[RFC3110]中。剩下的文本是公钥的Base64编码。
DNSSEC使用公钥加密对RRset进行签名和身份验证。数字签名存储
在RRSIG资源记录中,并用于[RFC4035]中描述的DNSSEC身份验证过程。验证器可以使用这些RRSIG RRs来验证区域中的rrset。RRSIG RR只能用于携带用于保护DNS操作的验证材料(数字签名)。
RRSIG记录包含具有特定名称、类和类型的RRset的签名。RRSIG RR指定签名的有效间隔
,并使用算法、签名者的名称和key tag来标识包含公钥的DNSKEY RR,验证器可以使用公钥来验证签名。
因为区域中的每个权威RRset都必须受到数字签名的保护,所以对于包含CNAME RR的名称,必须提供RRSIG RRs。这是对传统DNS规范[RFC1034]的一个更改,该规范规定,如果一个名称存在CNAME,那么它是该名称中唯一允许的类型。RRSIG和NSEC(参见第4节)必须与已签名区域中的CNAME资源记录具有相同的名字。
RRSIG RR类型的Type value是46。
RRSIG RR与class无关。
RRSIG RR必须与它所覆盖的RRset具有相同的类。
RRSIG记录包含具有特定名称、类和类型的RRset的签名。RRSIG RR指定签名的有效间隔,并使用算法、签名者的名称和key tag来标识包含公钥的DNSKEY RR,验证器可以使用公钥来验证签名。
RRSIG RR的RDATA由2字节的类型覆盖字段,1字节的算法字段,1字节的标签,4字节的原始TTL字段,字节的签名到期字段,4字节的签名起始字段,2字节的key tag字段,以及签名者的名字字段和签名字段。
1 1 1 1 1 1 1 1 1 1 2 2 2 2 2 2 2 2 2 2 3 3
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Type Covered | Algorithm | Labels |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Original TTL |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Signature Expiration |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Signature Inception |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Key Tag | /
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ Signer's Name /
/ /
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
/ /
/ Signature /
/ /
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
Key Tag字段包含验证此签名的DNSKEY RR的Key Tag值,以网络字节顺序排列。附录B解释了如何计算键标签值。
NSEC资源记录列出了两个单独的东西:下一个所有者名称(在区域的规范顺序中),它包含权威数据或委托点NS RRset,以及NSEC RR的所有者名称[RFC3845]处的RR类型集。区域中的完整NSEC RRs集指示区域中存在哪些权威rrset,并在区域中形成权威所有者名称链。如[RFC4035]所述,此信息用于为DNS数据提供经过身份验证的否认存在。
因为区域中的每个权威名称都必须是NSEC链的一部分,所以对于包含CNAME RR的名称,NSEC RRs必须出现。这是对传统DNS规范[RFC1034]的一个更改,该规范规定,如果一个名称存在CNAME,那么它是该名称中唯一允许的类型。RRSIG(参见第3节)和NSEC必须与带签名区域中的CNAME资源记录具有相同的名称。
请参阅[RFC4035],以了解区域签名者如何精确地确定它必须在区域中包含哪些NSEC RRs。
NSEC RR的Type value是47。
NSEC RR与class无关。
NSEC RR应该具有与SOA最小TTL字段相同的TTL值。这就是负缓存的精神([RFC2308])。
NSEC RR的RDATA如下图所示:
1 1 1 1 1 1 1 1 1 1 2 2 2 2 2 2 2 2 2 2 3 3
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
/ Next Domain Name /
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
/ Type Bit Maps /
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
DS RR引用一个DNSKEY RR,并在DNS DNSKEY身份验证过程中使用。通过存储key tag、算法编号和DNSKEY RR的摘要
,DS RR引用DNSKEY RR。请注意,虽然摘要应该足以识别公钥,但存储key tag和密钥算法有助于提高标识过程的效率。通过对DS记录进行身份验证,解析器可以对DS记录指向的DNSKEY RR验证
。密钥认证过程在[RFC4035]中有描述。
DS RR及其对应的DNSKEY RR拥有相同的所有者名称,但是它们存储在不同的位置。DS RR只出现在委托的上级
(父级)侧,是父区中的权威数据。例如,“example.com”的DS RR存储在“com”区域(父区域)中,而不是存储在 “example.com” 区域(子区域)中。对应的DNSKEY RR存储在“example.com”区域(子区域)中。这简化了DNS区域管理和区域签名,但为DS RR引入了特殊的响应处理需求;这些在[RFC4035]中有描述。
DS记录的Type value是43。
DS资源记录是class独立的。
DS RR没有特殊的TTL要求。
一个DS RR的RDATA包含一个2字节的key tag字段、一个1字节的算法字段、一个1字节的摘要类型字段和一个摘要字段。
1 1 1 1 1 1 1 1 1 1 2 2 2 2 2 2 2 2 2 2 3 3
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Key Tag | Algorithm | Digest Type |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
/ /
/ Digest /
/ /
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
Key Tag字段以网络字节顺序列出DS记录引用的DNSKEY RR的key tag。
DS RR使用的key tag与RRSIG RRs使用的key tag相同。附录B描述了如何计算key tag。
算法字段列出DS记录引用的DNSKEY RR的算法编号。
DS RR使用的算法编号与RRSIG和DNSKEY RRs使用的算法编号相同。附录A.1列出了算法编号类型。
通过包含DNSKEY RR的摘要,DS RR引用DNSKEY RR。摘要类型字段标识用于构造摘要的算法。附录A.2列出了可能的摘要算法类型。
DS记录通过包含DNSKEY RR的摘要来引用DNSKEY RR。
通过将DNSKEY RR的完全限定所有者名的规范形式与DNSKEY RDATA连接起来,然后应用摘要算法,计算摘要。
// “|” 表示连接
digest = digest_algorithm( DNSKEY owner name | DNSKEY RDATA);
DNSKEY RDATA = Flags | Protocol | Algorithm | Public Key.
摘要的大小取决于摘要算法和DNSKEY RR大小。在撰写本文时,唯一定义的摘要算法是SHA-1,它生成一个20字节的摘要。
DS RR跨区域边界链接身份验证链,因此在处理时需要格外小心。在DS RR中引用的DNSKEY RR必须是DNSSEC区域key。DNSKEY RR标志必须设置第7位标志。如果DNSKEY标志没有指明DNSSEC区域key,那么在验证过程中不能使用DS RR(和它引用的DNSKEY RR)。
RDATA部分的表示格式如下:
key tag字段必须表示为无符号十进制整数。
算法字段必须表示为无符号十进制整数或附录A.1中指定的算法助记符。
摘要类型字段必须表示为无符号十进制整数。
摘要必须表示为不区分大小写的十六进制数字序列。允许在十六进制文本中使用空格。
下面的例子显示了一个DNSKEY RR和它对应的DS RR。
dskey.example.com. 86400 IN DNSKEY 256 3 5 ( AQOeiiR0GOMYkDshWoSKz9Xz
fwJr1AYtsmx3TGkJaNXVbfi/
2pHm822aJ5iI9BMzNXxeYCmZ
DRD99WYwYqUSdjMmmAphXdvx
egXd/M5+X7OrzKBaMbCVdFLU
Uh6DhweJBjEVv5f2wwjM9Xzc
nOf+EPbtG9DMBmADjFDc2w/r
ljwvFw==
) ; key id = 60485
dskey.example.com. 86400 IN DS 60485 5 1 ( 2BB183AF5F22588179A53B0A
98631FAD1A292118 )
前四个文本字段指定名称、TTL、类和RR类型(DS)。值60485是对应的“dskey.example.com”的key tag。值5表示这个“dskey.example.com”使用的算法。DNSKEY RR。值1是用来构造摘要的算法,其余的RDATA文本是十六进制的摘要。
本节定义了资源记录的规范形式、DNS名称的规范排序和RRset内的资源记录的规范排序。构造NSEC名称链需要一个规范的名称顺序。为了构造和验证RRSIG RRs,需要一个规范的RR表单和RRset中的排序。
出于DNS安全的目的,通过将单个标签视为无签名左对齐的字节串来对所有者名进行排序。如果没有一个八位元,则在零值八位元之前进行排序,并且大写的US-ASCII字母被视为小写的US-ASCII字母。
要计算一组DNS名称的规范顺序,首先要根据最重要(最右边)的标签对名称进行排序。对于最重要的标签相同的名称,继续按照它们的下一个最重要的标签排序,依此类推。
例如,以下名称按规范DNS名称顺序排序。最重要的标签是“example”。在这个级别,“example”首先排序,然后是以“a.example”结尾的名字,然后以"z.example"结尾的名字。每一层的名称都以相同的方式排序。
example
a.example
yljkjljk.a.example
Z.a.example
zABC.a.EXAMPLE
z.example
\001.z.example
*.z.example
\200.z.example
出于DNS安全的考虑,RR的规范形式是RR的连线格式:
出于DNS安全的目的,对具有相同所有者名称、类和类型的RRs进行排序,方法是将每个RR的规范形式的RDATA部分视为左对齐的无符号八字节序列,其中在零八字节之前没有八字节。
[RFC2181]指定RRset不允许包含重复的记录(具有相同所有者name、class、type和RDATA的多个RRs)。因此,如果实现在将RRset置于规范形式时检测到重复的RRs,则必须将其视为协议错误。如果实现选择在健壮性原则的精神下处理这个协议错误(它接受的内容是自由的),那么为了计算RRset的规范形式,它必须删除所有的重复RR(s),只有一个例外。
DNSKEY、RRSIG和DS RRs使用8位数字来识别所使用的安全算法。这些值存储在资源记录RDATA中的“Algorithm Number”字段中。
有些算法只适用于区域签名(DNSSEC),有些只适用于事务安全机制(SIG(0)和TSIG),有些同时适用于两者。可用于区域签名的可能出现在DNSKEY、RRSIG和DS RRs中。如[RFC2931]所述,那些可用于事务安全的将在SIG(0)和密钥RRs中出现。
Zone
Value Algorithm [Mnemonic] Signing References Status
----- -------------------- --------- ---------- ---------
0 reserved
1 RSA/MD5 [RSAMD5] n [RFC2537] NOT RECOMMENDED
2 Diffie-Hellman [DH] n [RFC2539] -
3 DSA/SHA-1 [DSA] y [RFC2536] OPTIONAL
4 Elliptic Curve [ECC] TBA -
5 RSA/SHA-1 [RSASHA1] y [RFC3110] MANDATORY
252 Indirect [INDIRECT] n -
253 Private [PRIVATEDNS] y see below OPTIONAL
254 Private [PRIVATEOID] y see below OPTIONAL
255 reserved
6-251 可供IETF标准行动分配。
算法编号253保留给私人使用,永远不会分配给特定的算法。DNSKEY RR中的公钥区域和RRSIG RR中的签名区域以有线编码的域名开始,该域名不能被压缩。域名表示要使用的私有算法,公钥区域的其余部分由该算法确定。实体应该只使用它们控制的域名来指定它们的私有算法。
算法编号254保留给私人使用,永远不会分配给特定的算法。DNSKEY RR中的公钥区域和RRSIG RR中的签名区域以一个无符号长度字节开始,后跟该长度的BER编码的对象标识符(ISO OID)。OID表示正在使用的私有算法,其余的区域是该算法所需要的区域。实体应该只使用它们控制的oid来指定它们的私有算法。
DS资源记录类型中的“Digest Type”字段标识资源记录使用的加密摘要算法。下表列出了当前定义的摘要算法类型。
VALUE Algorithm STATUS
0 Reserved -
1 SHA-1 MANDATORY
2-255 Unassigned -
RRSIG和DS资源记录类型中的key tag字段提供了一种有效选择公钥的机制。在大多数情况下,所有者名称、算法和key tag的组合可以有效地识别DNSKEY记录。RRSIG和DS资源记录都有相应的DNSKEY记录。当有多个候选DNSKEY RR可用时,可以使用RRSIG和DS记录中的Key tag字段来帮助有效地选择相应的DNSKEY RR。
但是,必须注意,key tag不是惟一的标识符。从理论上讲,两个不同的DNSKEY RRs可能具有相同的所有者名称、相同的算法和相同的key tag。key tag用于限制可能的候选键,但它不能唯一地标识DNSKEY记录。实现不能假设key tag唯一地标识DNSKEY RR。
除了算法1外,所有DNSKEY算法类型的key tag都是相同的(算法1的key tag定义见附录B.1)。首先,将RDATA(有线格式)分成一系列的2个字节组。然后将这些组相加,忽略任何进位。
key tag算法的一个参考实现是一个ANSI C函数,如下所示,使用DNSKEY RR的RDATA部分作为输入。没有必要逐字使用下面的参考代码,但是key tag的数值必须与参考实现为相同的输入生成的数值相同。
请注意,计算key tag的算法与我们所熟悉的其他Internet协议中使用的校验和算法几乎相同,但并不完全相同。key tag必须使用这里描述的算法来计算,而不是使用互补校验和。
下面的ANSI C参考实现计算key tag的值。此参考实现适用于除算法1之外的所有算法类型(参见附录B.1)。输入是DNSKEY RR的RDATA部分的连线格式。代码是为了清晰而不是效率而编写的。
/*
* Assumes that int is at least 16 bits.
* First octet of the key tag is the most significant 8 bits of the
* return value;
* Second octet of the key tag is the least significant 8 bits of the
* return value.
*/
unsigned int
keytag (
unsigned char key[], /* the RDATA part of the DNSKEY RR */
unsigned int keysize /* the RDLENGTH */
)
{
unsigned long ac; /* assumed to be 32 bits or larger */
int i; /* loop index */
for ( ac = 0, i = 0; i < keysize; ++i )
ac += (i & 1) ? key[i] : key[i] << 8;
ac += (ac >> 16) & 0xFFFF;
return ac & 0xFFFF;
}
由于历史原因,算法1 (RSA/MD5)的key tag的定义与所有其他算法的key tag不同。对于使用算法1的DNSKEY RR,key tag被定义为公钥模量(即公钥模量的第4到最后一个字节和第3到最后一个字节)中24位中最有效的16位。
请注意,不推荐使用算法1。