Nodes/ComfyUI ARG Toolkit/RSA Signature Verification
ComfyUI Node

RSA Signature Verification

One boolean, four ways to get False

By AzelusLightvale·Created about a year ago·Updated a day ago· 3
RSA Signature Verification
  • public_key
  • data
  • signature
  • verify_result
◄salt_lengthMax Length►
◄signature_algorithm▾►
◄padding_algPSS►
◄prehashed—►
◄salt_length_manual—►

RSA Signature Verification answers one question - did the holder of this private key sign this exact data - and answers it with True or False. No exception on a bad signature. Which is great for wiring, and mildly cruel for debugging, because False covers a wrong key, wrong data, wrong hash, wrong padding and a wrong salt length all at once.

What it's for

Signing is the other half of RSA that people forget exists. Encryption hides a message; signing proves who wrote it. In an ARG context that's a lovely mechanic: a note in the graph carries a signature, players who find the right public key get a green light, and everyone else gets False. Outside puzzles, it's the usual "verify before you trust a downloaded artifact" job.

This is one of nine RSA nodes in AzelusLightvale's ComfyUI ARG Toolkit (ARG Toolkit/Cryptography/Modern/Asymmetric), a pack for cryptography and steganography inside ComfyUI. Its counterpart is RSA Signature Signer (RSASign), which produces the SIGNATURE object this node consumes.

How it works

The source does the thing you'd hope: pull a hash object from the signature_algorithm dropdown, build a padding object, call public_key.verify(...), and catch cryptography.exceptions.InvalidSignature to return False. Anything else - a signature of the wrong length, a broken key object - isn't caught and surfaces as a node error.

Two padding families, and they behave differently enough to be the main source of confusion:

  • PSS (default) is the modern randomised scheme. It takes a salt, and the salt_length dropdown (Max Length / Digest Length / Manual) controls it. PSS verification requires the same salt length the signer used. Get it wrong and you get a clean, confident False, not an error.
  • PKCS1v15 is the legacy deterministic scheme. The salt settings are ignored completely on this path - look at the source, the branch just calls PKCS1v15().

The optional prehashed boolean switches to utils.Prehashed(algorithm), meaning "the data you gave me is already the digest, don't hash it again." It must match whatever the signer did. If you're not sure, leave it off.

The inputs that matter

public_key is a KEYOBJ forced input - from RSA Public Key Bytes or RSA Public Numbers into Key. data is BYTESLIKE - usually from Bytes-like Object Encode. signature is its own SIGNATURE type, which only RSA Signature Signer produces; there's no stringy shortcut, so you can't paste a hex signature into the node. Set signature_algorithm to match the signer (the list has 15 entries: the SHA-2 family, SHA-3, BLAKE2b/2s, plus SHA1, MD5 and SM3 at the bottom for legacy puzzle work). Set padding_alg to match. Then salt_length, and if you choose Manual, salt_length_manual gives you an integer (1–65536) - which defaults to 1, not to anything sensible, so type the real number.

Output is verify_result, a BOOLEAN. Wire it into anything that takes a boolean - the pack's own conditional or logic nodes - or just read it off the node.

Install

ComfyUI Manager → search ComfyUI ARG Toolkit → install → restart → refresh the browser tab. Manual route:

cd ComfyUI/custom_nodes
git clone https://github.com/AzelusLightvale/ComfyUI-ARG-Toolkit
pip install -r requirements.txt

The heavy dependency is cryptography (pyca), not a model. Nothing to download into models/. One caution on the manual install: requirements.txt is a pinned uv lock that includes torch and torchaudio, so pip may swap out your CUDA torch build while installing a crypto pack. Manager handles this more gracefully; if you go manual, check torch.cuda.is_available() after.

Common issues

Always False even though you just signed the data yourself. Ten to one it's salt_length. Signer on Max Length, verifier on Digest Length → valid signature, rejected. Set both sides to the same value, or let both use the default. The same applies to the PSS/PKCS1v15 choice and the hash: any mismatch along those three settings is a False, never a helpful message.

False after re-running the signer. PSS signatures are randomised, so a signature is not byte-stable across runs - that's normal and not the problem. But if the data changed (a text box that got edited, a seed inside the message) then the signature covers different bytes now. Sign and verify the exact same BYTESLIKE object.

A node error instead of False. Only InvalidSignature is caught. A wrong-length signature or a mismatched key type raises, and the whole queue stops with a red node. That's your signal that something structural is off, not that the signature is merely invalid.

SM3 or MD5 and nothing works elsewhere. This pack exposes those for solving puzzles built with them; pyca will still refuse a combination it can't build (MD5 with PSS, for instance). Start with SHA256 + PSS and move only when the puzzle demands it.

CategoryARG Toolkit/Cryptography/Modern/Asymmetric

Inputs (8)

NameTypeDefaultDescription
public_keyKEYOBJ—
dataBYTESLIKE—
signatureSIGNATURE—
salt_lengthCOMBOMax LengthThe length of the salt.
signature_algorithmCOMBOThe hashing algorithm used for the signature.
padding_algCOMBOPSS2 options: PSS, PKCS1v15
prehashedoptBOOLEANWhether the data is prehashed or not.
salt_length_manualoptINT1–65536For only when salt_length is `Manual`.

Outputs (1)

NameTypeDescription
verify_resultBOOLEAN—