RSA Public Key Bytes
One mode throws the private half away
- serialized_key
- key_object
- public_key
- public_numbers
Everyone remembers to generate the private key. Almost nobody wires up the public one, and then the verification node returns false forever and they assume the signer is broken. If you're signing images or messages in ComfyUI, this is the node that produces the half you publish - and it has one mode you should probably never use.
What it's for
An RSA signature is only useful if someone can check it without holding your private key. That's the whole point: you sign with the private half and hand out the public half so anyone can confirm the message wasn't touched. In ComfyUI ARG Toolkit, this is what RSA Signature Verification wants, and what you'd paste next to a puzzle image so a solver can prove they found the real clue.
How it works
The mechanism is quieter than the name suggests. Depending on key_source, the node either calls rsa.generate_private_key(...) itself and takes .public_key() off the result, or accepts a private key object you hand it and derives the public half. Either way only the public part gets serialized, via public_bytes(encoding, format).
Which is the catch worth saying out loud: "Fresh Key" mode generates a private key, keeps it just long enough to compute the public one, then discards it. The keypair exists; you only get the half you can't sign with, so a sign-then-verify loop built entirely on this node can never succeed. Use Fresh Key for a plausible key to publish - an ARG prop, a decoy - and "From Loaded Key" for everything real.
In that second mode, the serialized_key input must be a private key object. The source checks isinstance(serialized_key, rsa.RSAPrivateKey) and throws "Missing private keys for RSA public key generation." otherwise, so feeding it a PEM Serialized Public Key Loader output - the intuitive move - fails. Valid sources are key_object from RSA Private Key Bytes, an RSA Private Numbers into Key output, or a private key loader (PEM/DER/OpenSSH, all of which take the key's bytes on keyfile, not a file path).
The inputs that matter
key_source- "Fresh Key" or "From Loaded Key". Note the tooltips mention "From Fresh Key"; the actual enum value is "Fresh Key". Mirror-image of the usual confusion, no functional harm.formatting-SubjectPublicKeyInfo(default) gives the standardBEGIN PUBLIC KEYblock that OpenSSL, Python, Node and everything else reads.PKCS1gives the olderBEGIN RSA PUBLIC KEYblock. Pick it only if the other end demands it; both are RSA-specific anyway, so PKCS1 buys compatibility and nothing more.encoding- PEM (text, wraps nicely) or DER (raw bytes).fresh_key_sizeandpublic_exponent- both are labelled as applying only in Fresh Key mode, and they genuinely are ignored otherwise. Wire them, leave them, doesn't matter.
Outputs mirror the private node: key_object (KEYOBJ, goes straight into the verifier or RSA Encrypt Data), public_key (BYTESLIKE, the serialized bytes you'd decode to text and share), and public_numbers (NUMOBJ, the n and e as integers - feed it to RSA Public Numbers Values if you need to print the modulus, or to reconstruct a key from numbers you were handed).
The workflow you actually want
Private key node → key_object → this node in "From Loaded Key" → key_object → verifier. Same private key object you gave the signer. The derivation is deterministic, and that's exactly the property that makes verify return true instead of quietly lying.
Installing
Manager: search ComfyUI ARG Toolkit, install, restart. Manual:
cd ComfyUI/custom_nodes
git clone https://github.com/AzelusLightvale/ComfyUI-ARG-Toolkit
Then install only what's missing. The repo's requirements.txt is a uv lockfile pinning torch==2.14.1 and torchaudio==2.11.0; run it against a live ComfyUI environment and you risk replacing the torch you built CUDA against. These nodes need cryptography and nothing else:
pip install cryptography
The pack also declares Python >=3.12, and its __init__.py imports every module in src/ eagerly - miss stegano or invisible-watermark and the whole pack fails to load, so you see no ARG Toolkit nodes at all, not just a missing one. The traceback names the culprit.
When it goes wrong
Missing private keys for RSA public key generation - you fed it a public key (or nothing at all) while in "From Loaded Key". Switch source or wire the private object.
Verifier says false - check which public key you derived from. A Fresh Key public key verifies nothing.
Garbled PEM after decoding - encoding here and the decode mode on Bytes-like Object Decode are unrelated axes. DER bytes decoded as UTF-8 give replacement characters; base64 them instead.
This is a solo-authored, WIP corner of a niche pack, so there's no crowd-sourced answer key when it misbehaves - the source is about sixty lines and is the real documentation.
Inputs (6)
| Name | Type | Default | Description |
|---|---|---|---|
| key_source | COMBO | Fresh Key | The source of the private key to be used to sign the message |
| encoding | COMBO | PEM | 2 options: PEM, DER |
| formatting | COMBO | SubjectPublicKeyInfo | 2 options: SubjectPublicKeyInfo, PKCS1 |
| serialized_keyopt | KEYOBJ | Only applicable if key_source is `From Loaded Key`. | |
| fresh_key_sizeopt | INT | 2048512–8192 | Only applicable if key_source is `From Fresh Key`. |
| public_exponentopt | INT | 655371–4294967296 | Only applicable if key_sourcce if `From Fresh Key`. |
Outputs (3)
| Name | Type | Description |
|---|---|---|
| key_object | KEYOBJ | — |
| public_key | BYTESLIKE | — |
| public_numbers | NUMOBJ | — |