簡體   English   中英

驗證 NSEC3 記錄

[英]Verifying NSEC3 records

我在擺弄 DNSSEC,我想嘗試驗證dnssec-signzonebind9-utils生成的 NSEC3 記錄(我認為這是有效的)。 這是我的區域文件:

$ORIGIN dnssectest.mvolfik.tk.
$TTL 120
@   SOA dnssectestns.mvolfik.tk. email.example.com. 15 259200 3600 300000 3600
    A   192.168.0.101
s3c A   192.168.0.101

$INCLUDE zsk.key
$INCLUDE ksk.key

ZSK 和 KSK 使用dnssec-keygen -a ECDSAP256SHA256 dnssectest.mvolfik.tk. (分別加-f KSK

然后我使用命令dnssec-signzone -3 deadbeef -H 5 -o dnssectest.mvolfik.tk -k ksk.key zonefile zsk.key (使用帶有deadbeef hex salt 的 NSEC3,5 次迭代)

我在zonefile.signed中得到了以下 NSEC3 記錄:(省略了 RRSIG 和 DNSKEY 無關緊要;A 和 SOA 沒有改變)

            0   NSEC3PARAM 1 0 5 DEADBEEF
F66KKS17FM851AVA4EARFHS55I3TOO85.dnssectest.mvolfik.tk. 3600 IN NSEC3 1 0 5 DEADBEEF (
                    D60TA5J5RS4JD5AQK25B1BCUAHGP4DHC
                    A SOA RRSIG DNSKEY NSEC3PARAM )
D60TA5J5RS4JD5AQK25B1BCUAHGP4DHC.dnssectest.mvolfik.tk. 3600 IN NSEC3 1 0 5 DEADBEEF (
                    F66KKS17FM851AVA4EARFHS55I3TOO85
                    A RRSIG )

現在我知道該區域中唯一的域是s3c.dnssectest.mvolfik.tk. dnssectest.mvolfik.tk. ,我假設下面的 Python 腳本會得到與上面簽名區域文件中相同的哈希值:(來自RFC 5155中的偽代碼)

import hashlib
def ih(salt, x, k):
    if k == 0:
        return hashlib.sha1(x + salt).digest()
    return hashlib.sha1(ih(salt, x, k-1) + salt).digest()

print(ih(bytes.fromhex("deadbeef"), b"s3c.dnssectest.mvolfik.tk.", 5).hex())

print(ih(bytes.fromhex("deadbeef"), b"dnssectest.mvolfik.tk.", 5).hex())

但是,我得到了b58374998347ba833ab33f15332829a589a80d82545e01397a776ee73aa0372aea015408cc384574 我究竟做錯了什么?

所以我查看了dnspython源代碼,發現了nsec3_hash function。 事實證明,名稱必須是有線格式(意味着刪除點,而是在標簽前面加上一個長度字節 - \x03s3c\x10dnssectest\x07mvolfik\x02tk\x00等,最后是 null 字節)。 結果用base32(0-9A-V)編碼,而不是十六進制。 使用 dnspython 庫可能更容易,但這里是完整的(有點天真)代碼:

import hashlib, base64

b32_trans = str.maketrans(
    "ABCDEFGHIJKLMNOPQRSTUVWXYZ234567", "0123456789ABCDEFGHIJKLMNOPQRSTUV"
)


def ih(salt, x, k):
    if k == 0:
        return hashlib.sha1(x + salt).digest()
    return hashlib.sha1(ih(salt, x, k - 1) + salt).digest()


def nsec3(salt, name, k):
    if not name.endswith("."):
        name += "."
    labels = name.split(".")
    name_wire = b"".join(len(l).to_bytes(1, "big") + l.lower().encode() for l in labels)
    digest = ih(bytes.fromhex(salt), name_wire, k)
    return base64.b32encode(digest).decode().translate(b32_trans)

print(nsec3("deadbeef", "dnssectest.mvolfik.tk.", 5))
print(nsec3("deadbeef", "s3c.dnssectest.mvolfik.tk.", 5))

這將獲得在 NSEC3 記錄中看到的正確哈希值

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM