DNS TSIG
Sign and verify DNS messages with RFC 8945 TSIG (Transaction SIGnature) — the shared-key HMAC that authenticates the transaction between a resolver and a server (zone transfers, dynamic updates, and any query/response pair) and proves it was not tampered with in flight. TSIG complements the existing DNSSEC and DANE primitives: DNSSEC authenticates zone data end-to-end, while TSIG authenticates a single hop's transaction with a pre-shared key.
sign(message, opts) appends a TSIG resource record to a DNS message and returns the signed wire bytes; verify(message, opts) locates the TSIG record, recomputes the HMAC over the RFC 8945 §4.3.3 digest, compares it in constant time, and checks the time window (the signature is only valid within fudge seconds of timeSigned). The default MAC algorithm is HMAC-SHA-256; SHA-384 / SHA-512 are available, and the broken HMAC-MD5 / HMAC-SHA-1 algorithms are refused unless allowLegacy is set. Signing a response chains the request's MAC into the digest (requestMac) per §5.4.1.
b.network.dns.tsig.sign(message, opts) #
{
keyName: string, // REQUIRED — the shared-key name
secret: string | Buffer, // REQUIRED — base64 string or raw bytes
algorithm: string, // default: "hmac-sha256"
fudge: number, // default: 300 (seconds)
time: number, // default: now (Unix seconds)
originalId: number, // default: the message's own ID
requestMac: Buffer, // when signing a response (§5.4.1)
error: number, // default: 0 (NOERROR)
otherData: Buffer, // default: empty
allowLegacy: boolean, // permit HMAC-MD5 / HMAC-SHA-1
}
Append a TSIG resource record to a DNS message (a Buffer of wire bytes) and return the signed wire Buffer. The MAC is the HMAC over the message plus the RFC 8945 §4.3.3 TSIG variables. Returns { wire, mac } — wire is the message with the TSIG RR appended and ARCOUNT incremented, and mac is the raw HMAC (keep it to verify the matching response).
var signed = b.network.dns.tsig.sign(queryWire, {
keyName: "update.key.", secret: "",
});
socket.send(signed.wire);
b.network.dns.tsig.verify(message, opts) #
{
keys: object, // { "": { secret, algorithm } }
keyName: string, // single-key form (with secret)
secret: string | Buffer, // single-key form
algorithm: string, // expected algorithm (single-key form)
now: number, // default: now (Unix seconds)
requestMac: Buffer, // when verifying a response (§5.4.1)
allowLegacy: boolean,
}
Verify the TSIG record on a DNS message: locate the trailing TSIG RR, recompute the HMAC over the RFC 8945 §4.3.3 digest, compare it in constant time, and check that now is within fudge seconds of timeSigned. Returns { valid, keyName, algorithm, timeSigned, fudge, error, macValid, timeValid, reason }; valid is true only when the MAC matches, the time window holds, and the embedded error is NOERROR. Never throws for an authentication failure — only for a malformed message or unknown key shape.
var r = b.network.dns.tsig.verify(received, {
keys: { "update.key.": { secret: "" } },
});
if (!r.valid) refuse(r.reason);
Last updated 2026-08-08T16:39:49.652Z by seeder.