我正在为计费系统完成域名注册商插件(在这种情况下也管理域配置),最后一点与实施DNSSEC支持有关。
计费系统将以下SAMPLE DNSSEC相关数据发送到我的PHP插件:
'dnsSecInfo' =>
array (
0 =>
array (
'keyAlg' => 5,
'digestAlg' => 1,
'digest' => '1d181b34061ee98088b7a9e6db6e41a130674df0',
'key' => 'AwEAAaqZeENizOE6uvpDtIfQBB26YebvRdZA/ZjXjKLZdMmMK641sBIvho+yrTveIYclM+8lEVHiq64MY8R2G1IPmKDKXG26rM7NVE0Qx1KL2wRVbRrduRdBmKgJo3XQ3niueviKYXXmeVIO3EhrJsCq272Tm3DaDvng/M7uw1vDnanR2pYNcxI08fZOA6PLGDoUWlDNLGAHHkCvfdWUktVt1DA0GtL/qE/WUgxK6hJyeaXXb0+yq3qCMZh48WgluMFib54D0GN3PI3ZZvBMblAZHmFGqgyVwtPKEimXm/VREe2QtZy3cRgPbfOuiQi8gRhzO+/If8Wi9YnyLovjdsSjRsE=',
),
),
RFC 4034有以下内容:
2.1. DNSKEY RDATA Wire Format
The RDATA for a DNSKEY RR consists of a 2 octet Flags Field, a 1
octet Protocol Field, a 1 octet Algorithm Field, and the Public Key
Field.
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 /
/ /
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
相同协议的附录B:
The input is the wire
format of the RDATA portion of the DNSKEY RR.
.....
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;
}
注册域名的注册管理机构需要 4个必填字段:
其他可选字段包括:标志,协议,算法,公钥(插件中的'键')
现在这是我迷路的地方...... 如何在PHP中实现上述C函数?
key
char数组? (我正在争先恐后的旗帜
八位字节是默认值,如0,256或257还不确定),然后
Protocol octet是示例中的keyAlg值5,后跟
算法八位字节总是3,最后 - 关键八位字节是
键。这是猜对吗??)& 0xFFFF
目的是什么?什么是PHP等价物?我倾向于认为它几乎相同,因为PHP是基于语法的C语言......但是如果没有正确的输入/输出示例,我很难确定我是否正确... 答案 0 :(得分:0)
你的问题不是很清楚。您是在构建注册商系统还是与注册商建立联系的系统?
此外,你的标题谈到构建DNSKEY RDATA,但是你的问题的全部内容都涉及计算keyid / keytag,它无论如何都不会与DNSKEY记录一起发布(仅与RRSIG记录一起发布,但像dig
这样的工具可以重新计算它以显示它作为注释,当你看到DNSKEY记录时帮助你。)
在任何一种情况下,您都不必处理DNSSEC数据线格式。在第一种情况下(注册商系统),您通常使用具有DNSSEC数据特定扩展名的EPP与注册表进行交互,称为secDNS。见RFC5910
现在,至于DNSSEC本身。它使用密码术,因此最好不要尝试重做手工操作。似乎PHP有Net_DNS2
可以提供帮助。
但我不明白为什么你必须清除这些价值观。如果您是注册商,则将您客户给您的价值传递给注册管理机构;你可以稍微验证一下它们的语法,但除此之外你只需要传递它们。如果您将数据提交给注册商,作为客户,您再次从某个地方获取此数据,我不明白为什么您必须采取行动。
现在你谈论一个注册表,所以现在我会想象你是一个注册商。首先阅读RFC5910。您将看到有两个接口,实际上有3个案例,按现在最常用的顺序排列:
dsData
界面,您作为注册商向注册管理机构提供基本上注册管理机构将发布的DS记录;这些数据(确实是4个字段,您在第一个集合中列出它们)是根据您或托管公司将在域zonefile中作为DNSKEY记录发布的密钥构建的。keyData
界面,同样有4个字段,但与之前的4个字段不同(第二个集合中有,或者帖子顶部的PHP结构),实际上你发送了注册表密钥(其公共部分),注册表将从中计算DS记录本身dsData
且内部带有keyData
的混合大小写,这意味着您要发送DS以发布和相关密钥,该密钥是无用的,但注册表可以重做DS计算检查,从密钥出发。 如果您阅读RFC,您将对2组4个字段及其含义进行解释。
对于其中一些,您只能使用几个离散值:
至于你的具体问题,似乎你试图从关键内容中计算keyID / keytag(令人惊讶的是,已经发现这个算法有缺陷,但无论如何),正如我之前所说,你不应该尝试重做这个你自己。如果可能的话,尝试找一个为你做的PHP库,或者至少使用现有的工具,但这取决于你的密钥生成方式,你从哪里获取它们等等...... 例如,请参阅此工具:https://linux.die.net/man/8/dnssec-keygen
否则你有这段代码:https://www.v13.gr/blog/?p=239 它是在Python中,但您可以从中派生出PHP版本。请记住,密钥标签仅取决于密钥内容,其中DS哈希值取决于密钥和域名(因此即使您对不同的域名使用相同的密钥,DS值也会不同)。
所以对于你的1)+ 2),这是keyData
接口所需的4个字段:
iana.org
的第一个链接对于3):执行& 0xFFFF
意味着取16位最低有效位(通常在写入时最右边的16位),因为&
是逻辑AND而0xFFFF是2 ^ 16 - 1(65535),即16位设置为值1.否则,如果最终值超过65535,我们只保留部分操作,因为keytag被定义为16位值。
顺便说一下,您可以使用dnssec-keygen
命令创建密钥及其密钥标记,以验证您自己的算法。
dnssec-keygen -a RSASHA256 -b 2048 test1
将产生:
Generating key pair.......+++ ............................+++
Ktest1.+008+05433
在生成的文件名中,008
是算法(来自RSASHA256),05433
是计算的keyId(keytag)。如果你查看.key
中计算完成的文件,你在完整的DNSKEY记录中,按照编码为Base64的密钥,按照规范(这是计算keyid的算法的输入)。
我希望你能在上面的内容中找到至少一些有用的想法,但我担心不能更好地理解你的问题,以便更具体。