ConcatKDF (HMAC) Key Derivation
The key-derivation variant that adds a salt
- message
- other_info
- salt
- derived_key
ConcatKDFHMAC_Derive is the cousin of the ConcatKDF (Hash) derivation node, with one meaningful upgrade: instead of building the derived key from a plain hash chain, it feeds the hash through an HMAC construction - and, more practically, it accepts an optional salt to mix in. If the Hash variant is the "derive a session key from an ECDH shared secret" node, this is the "derive a key and make it harder to precompute" node. Same NIST SP 800-56A / X9.63 family, one extra dial and a stronger construction under the hood.
When do you actually pick HMAC over Hash? When you have a salt available and want the extra margin. An HMAC-based KDF binds the salt and the context more thoroughly into every block of output, and it resists some theoretical structure-finding attacks on plain hashes better. The pack's own tooltip on the salt input says it plainly: optional but highly recommended, "ideally with as many bits of entropy as the security level of the hash function." In practice: if you're deriving keys in a real protocol or a serious ARG mechanic, reach for this variant and feed it a fresh random salt from the pack's SystemRandom node.
How it works
It wraps cryptography's ConcatKDFHMAC. The core inputs match the Hash variant: message (the raw secret to derive from, in bytes), length (derived key size, default 32 bytes, 16–256 range in 16-byte steps), and algorithm (the full roster - SHA2, BLAKE2b/s, SHA3, SHA1, MD5, SM3). other_info is optional context mixed into the derivation. The difference is the optional salt input, a BYTESLIKE value fed into the HMAC; leave it unwired and the node proceeds without one. Output is derived_key, a BYTESLIKE blob.
The salt's job: it makes the same message derive a different key depending on the salt, so even if two parties share a secret, they can namespace their keys. That's the property you lean on when the same shared secret is used for multiple purposes (encryption here, integrity there) and you don't want cross-use key reuse.
The inputs that matter
message- the raw shared secret, must be bytes.length- derived key length in bytes (default 32).algorithm- hash used inside the HMAC.salt(optional) - random bytes to bind into the key. Generate with SystemRandom ("Random Nonce Generator"); a 32-byte salt is a reasonable default.other_info(optional) - context bytes.
Output: derived_key (BYTESLIKE).
Installing it
Part of the ComfyUI ARG Toolkit pack. Install via ComfyUI Manager (search "ComfyUI ARG Toolkit") or:
cd ComfyUI/custom_nodes
git clone https://github.com/AzelusLightvale/ComfyUI-ARG-Toolkit
Restart ComfyUI. Runs on the pack's cryptography dependency (with secretpy, stegano, invisible-watermark, reedsolo, and transitive torch/opencv-python). No models, no API keys.
Gotchas
Same rules as the Hash sibling, plus one: the salt is part of the key. The decrypting/verifying side must use the same salt - a different salt silently produces a different key. Since length moves in 16-byte steps, you can't request arbitrary sizes, and message has to arrive as BYTESLIKE (ByteslikeEncode is the on-ramp). And if you're choosing between this and the Hash variant: this one's the better default when you control the salt and want the stronger construction.
Inputs (5)
| Name | Type | Default | Description |
|---|---|---|---|
| length | INT | 3216–256 | The desired length of the derived key in bytes. |
| message | BYTESLIKE | The message to derive key from. Must be bytes. | |
| algorithm | COMBO | The algorithm to use for hash generation. | |
| other_infoopt | BYTESLIKE | Application-specific context information. If left empty, will pass an empty byte string. | |
| saltopt | BYTESLIKE | A salt. Optional, but highly recommended, ideally with as many bits of entropy as the security level of the hash function. |
Outputs (1)
| Name | Type | Description |
|---|---|---|
| derived_key | BYTESLIKE | — |