附录 B. Key Tag 计算
RRSIG 和 DS 资源记录类型中的 Key Tag 字段提供了一种高效选择公钥的机制. 在大多数情况下, 所有者名称, 算法和密钥标签的组合可以高效标识 DNSKEY 记录. RRSIG 和 DS 资源记录都有对应的 DNSKEY 记录. 当存在多个候选 DNSKEY RR 时, RRSIG 和 DS 记录中的 Key Tag 字段可用于帮助高效选择对应的 DNSKEY RR.
然而, 必须注意, 密钥标签不是唯一标识符. 两个不同的 DNSKEY RR 可能具有相同的所有者名称, 相同的算法和相同的密钥标签. 密钥标签用于缩小可能的候选密钥范围, 但不能唯一标识 DNSKEY 记录. 实现禁止假定密钥标签能够唯一标识 DNSKEY RR.
除算法 1 外, 所有 DNSKEY 算法类型的密钥标签计算方式都相同 (算法 1 的密钥标签定义见附录 B.1). 密钥标签算法是将 DNSKEY RDATA 的线格式拆分为 2 八位字节组后求和. 首先, 将 RDATA (线格式) 视为一系列 2 八位字节组. 然后将这些组相加, 忽略所有进位比特.
下面给出密钥标签算法的参考实现, 形式为一个 ANSI C 函数, 以 DNSKEY RR 的 RDATA 部分作为输入. 实现不必逐字使用该参考代码, 但对于相同输入, Key Tag 的数值必须与参考实现生成的值完全相同.
注意, 用于计算 Key Tag 的算法几乎等同于许多其他互联网协议中使用的一补校验和, 但并不完全相同. 计算 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;
}
B.1. 算法 1 (RSA/MD5) 的 Key Tag \
由于历史原因, 算法 1 (RSA/MD5) 的密钥标签定义不同于所有其他算法的密钥标签. 对于使用算法 1 的 DNSKEY RR, 密钥标签定义为公钥模数最低有效 24 位中的最高有效 16 位, 换言之, 即公钥模数倒数第 4 和第 5 个八位字节.
注意, 不推荐使用算法 1.
相关章节导航:
- 上一节: 附录 A. DNSSEC Algorithm 和 Digest Type
- 返回: 目录