Image Encryption
Scramble any image with a password — and get a crypto scorecard with it
- image
- encrypted_image
- metadata
- security_report
You've got an image you don't want the next person who opens the folder to actually see - a private portrait, an unreleased generation, a batch you're sending somewhere you don't fully trust. Feed it to this node with a password and it comes out the other end as pure static: an encrypted IMAGE that only turns back into a picture with the matching password. That's the whole pitch, and it does it with zero API calls and no model download.
Be honest about the context up front: this pack is new, tiny, and nobody on Reddit is talking about it yet (checking the corpus for "image encryption" in ComfyUI turns up nothing). It's an educational/utility toy from a single author, built to a documented design worklog, not an audited security product. Great for keeping images out of plain sight; don't build a payments system on it.
What actually happens to the pixels
It's a classic image-scrambling pipeline, straight out of the image-cryptography literature. The password is hashed with SHA-256 into a key, then the image is split into square blocks of block_size pixels. Three things happen per round, in order:
- Block permutation - the blocks are reordered along a space-filling curve.
HilbertandMortonare deterministic fractal orderings;Randomshuffles. - Inner-block permutation - pixels get shuffled inside each block the same way.
- Diffusion - every byte is XORed against a keystream so the pixel values change, not just their positions.
XORuses a SHA-256-derived stream,Chaotic XORmixes in a logistic-map chaos stream,AES-CTRuses real AES in counter mode.
The diffusion is chained (each byte depends on the one before it), which is what makes it exactly reversible on the decrypt side. rounds (default 3) repeats the whole cycle, and that's genuinely the strength knob: more rounds, harder to crack, slower.
The inputs that matter
The full input list is image, password, block_size, permutation_mode, diffusion_mode, rounds, and seed. A beginner sets exactly three of them:
password- the one that matters. Write it down. There's no recovery, and it's not stored anywhere you can fish it out of later.diffusion_mode- the only one with a real gotcha:AES-CTRneeds thecryptographypackage installed.XOR(the default) andChaotic XORrun on plain ComfyUI.rounds- crank this up for a tougher scramble, leave it at 3 otherwise.
block_size (default 16), the two permutation/diffusion dropdowns, and seed are "sensible defaults are fine" territory; seed just varies the diffusion stream.
Three outputs, and what each is for
encrypted_image(IMAGE) - the static-looking result. Wire this to aSaveImageor into the decrypt node.metadata(JSON) - the recipe: block size, rounds, permutation, diffusion, seed, original dimensions, version. You need this to decrypt, and there's a neat trick: the node attaches it to the image tensor and stuffs it intoextra_pnginfo, so a plainSaveImagewrites it into the PNG's text chunks. The encrypted file carries its own decryption parameters (this is the same metadata-in-PNG plumbing the whole ecosystem runs on - see image-io-metadata.md).security_report(JSON) - six numbers: entropy, horizontal/vertical/diagonal correlation,npcr, anduaci. These are the standard academic metrics for "does this ciphertext actually look random." Entropy near 8 and correlations near 0 means the scramble worked; a flat solid-color input will score badly and that's the node telling you it has nothing to hide.
Batches work - feed it a batch and both JSON outputs become per-image lists.
Install and gotchas
ComfyUI Manager: search ComfyUI-Image-Encryption. Or by hand:
cd ComfyUI/custom_nodes
git clone https://github.com/Zhuozhuo-219/ComfyUI-Image-Encryption
# only needed if you want AES-CTR diffusion mode:
pip install "cryptography>=42.0.0"
Then restart ComfyUI. If you pick AES-CTR without installing cryptography, you'll get a clean RuntimeError telling you exactly that - go install it or switch back to XOR. And remember: the password is a password. Lose it, and "encrypted" becomes "permanently destroyed."
Inputs (7)
| Name | Type | Default | Description |
|---|---|---|---|
| image | IMAGE | — | |
| password | STRING | — | |
| block_size | INT | 161–256 | — |
| permutation_mode | COMBO | Hilbert | 3 options: Hilbert, Morton, Random |
| diffusion_mode | COMBO | XOR | 3 options: XOR, Chaotic XOR, AES-CTR |
| rounds | INT | 31–16 | — |
| seed | INT | 00–18446744073709550000 | — |
Outputs (3)
| Name | Type | Description |
|---|---|---|
| encrypted_image | IMAGE | — |
| metadata | JSON | — |
| security_report | JSON | — |