vs the alternatives

How deny.sh compares.

VeraCrypt, TrueCrypt, age, PGP, OTR. Each one is good at the threat model it was built for. None of them are deniability infrastructure in the sense this site uses the term, because each one stops at the library or the volume manager. Side-by-side comparison below, with honest notes on what we don't do.


At-rest file encryption tools that claim some form of deniability or are commonly compared with deny.sh. OTR (messaging) is in a separate section below.

deny.sh VeraCrypt TrueCrypt age + wrappers PGP/GPG
Strong encryption (AES-256 or equiv.) AES-256-CTR ChaCha20-Poly1305 AES-256-CFB
Claims plausible deniability Via wrappers
Cryptographic deniability (formal) construction
Mechanism Two-secret KDF, no headers Hidden volume inside outer volume Hidden volume inside outer volume Decoy stub + experimental wrappers Standard AEAD with key id
Detectable file format No header, no signature Random-looking container, free-space anomaly possible Same as VeraCrypt age v1 magic bytes header PGP packet header / armor
Multiple decoys per ciphertext Unlimited 1 hidden volume per outer 1 hidden volume per outer
Works on single files (no container) Volume / partition only Volume / partition only
Full-disk encryption use VeraCrypt
Browser-based (zero install) Desktop only Desktop only CLI only CLI / desktop client
Programmatic SDK / API TS, Rust, Go, Python Go library CLI / GPGME
Open source Apache 2.0 SDK Apache 2.0 TrueCrypt licence BSD-3-Clause GPL
Maintained / actively developed ✗ Discontinued 2014
Independent audit Construction proof published; external audit on roadmap QuarksLab 2016 OCAP audit 2014 RFC 4880 standard
Decoy tripwires (alert on decoy decrypt) controlData + plaintext kinds

veracrypt & truecrypt

VeraCrypt and TrueCrypt: hidden volumes.

VeraCrypt is the closest competitor in the deniability space, and the only tool here we recommend pairing with deny.sh rather than replacing. Its threat model and ours are different.

VeraCrypt encrypts whole volumes or whole disks. A hidden volume sits inside the unused space of an outer volume; you can mount the outer with one password and the hidden one with another. This works well when the threat is offline analysis of a stolen drive.

The hidden-volume mechanism has structural limits. The outer volume is a fixed-size encrypted container. The hidden volume lives in what looks like free space, and recent accesses to the outer volume can corrupt or overwrite the hidden one if you forget to mount in protect-hidden mode. Forensic analysis of the free-space distribution and the file system metadata can sometimes flag the presence of a hidden volume; the security relies on the outer volume looking convincingly used.

TrueCrypt is the predecessor; development stopped in May 2014 with the cryptic using TrueCrypt is not secure notice. The OCAP audit later that year found the cryptography was sound. People still use it; we don't recommend it given the lack of maintenance.

deny.sh has no volumes, no containers, no free-space heuristic. A single file decrypts to different valid plaintexts depending on which control file is supplied. The file size is fixed by the plaintext, not by an outer container that has to be plausibly populated. There is no analogous metadata-side-channel.

Where VeraCrypt wins: full-disk and full-volume encryption. If you need an encrypted operating system partition or a 2 TB hidden archive, VeraCrypt is the right tool. Use both: VeraCrypt for the disk, deny.sh for individual files that need cryptographic deniability.

cipheredge

CipherEdge: two records vs one ciphertext.

CipherEdge is the closest tool to deny.sh on the consumer side: browser-based, client-side AES-256-GCM, zero-knowledge (the key lives in the URL fragment and never reaches their server), and a real-plus-decoy story aimed at the same seed-phrase, journalist and coercion use-cases. It's well-built and the threat model is one we take seriously.

The difference is structural, and CipherEdge states it plainly: its two secrets are created completely independently, each stored as a separate, unlinked record, which it describes as structurally identical to VeraCrypt's hidden volume. Deniability there is a property of the storage layout (the server holds two blobs and claims it can't link them) rather than of a single construction. That puts the security on the assumption that nothing (creation order, timing, access logs, backup snapshots, traffic correlation, or a future metadata leak) ever ties the two records together.

deny.sh is one ciphertext, multiple plaintexts. There is no second record to link, because there is no second record. A single blob, indistinguishable from random data of its length, decrypts to a real value or a decoy depending only on which control file is supplied. The deniability is a property of the construction itself, not of two artefacts being kept apart. There is no which one was made first question to answer, because there is only one artefact.

Both are honest zero-knowledge designs. If you want the simplest possible share-a-link consumer flow, CipherEdge is fine. If you want the deniability to hold even when an adversary can see your storage, your backups and your access patterns (and you want the same primitive available as an SDK, CLI and agent substrate, not just a web form) that is the case deny.sh is built for.

age

age and the experimental wrappers.

age is the modern successor to PGP for file encryption. Clean format, sensible defaults, ChaCha20-Poly1305 AEAD with X25519 key agreement. We respect it; it's well-designed encryption software.

age does not natively claim deniability. Its files start with a recognisable age-encryption.org/v1 header line; the file is unmistakably an age-encrypted file. Several experimental wrappers exist (decoy stubs, dual-recipient tricks, pure header stripping) but none of them ship a formal deniability proof and most introduce detectable structural irregularities of their own.

deny.sh ships no header, no version line, no recognisable bytes. The ciphertext is indistinguishable from random data of the same length. The deniability is a property of the construction, not of how the file is wrapped after the fact.

pgp / gpg

Why PGP/GPG isn't deniable (and never claimed to be).

PGP encrypts a file. It does this well, has been audited for thirty years, and underpins most of the email and software-signing world. It also makes no deniability claim.

A PGP-encrypted file is unmistakably a PGP-encrypted file. There's a packet header, a recipient key id, often an ASCII armor wrapper. When the file leaks, the existence of the encrypted file is itself the leak; the recipient key id can identify the intended reader. There is no decoy, no second plaintext, no construction-level deniability.

If you're trying to deny that anything was encrypted at all, or to produce a different valid plaintext on demand, PGP is the wrong tool. If you want strong asymmetric encryption with a long audit history and broad ecosystem support, PGP is fine.

otr / signal

OTR / Signal: deniability for messages, not files.

Off-the-Record Messaging and the Signal Protocol both implement cryptographic repudiation for live conversations. Forward secrecy plus malleable MACs mean that any single message can be forged after the fact by either participant; you can't prove who wrote what.

This is a different threat model. OTR-style deniability defends a conversation participant against a transcript being used as evidence. It applies to live, two-party messaging with key rotation, not to data sitting on a disk or in a backup.

deny.sh is for at-rest data. Files in cloud-synced backups, vault entries on a stolen laptop, agent secret stores, archived datasets. If you need deniable messaging, use Signal or OTR. If you need deniable storage, use deny.sh. They don't compete; they cover different surfaces.

honeytokens / canary services

Thinkst Canary, Canarytokens, GitGuardian: detection without the substrate.

Thinkst Canary, the Canarytokens project, and the broader honeytoken category (AWS canary keys, GitGuardian honeytokens, Spectral, Doppler decoy secrets) all answer the same question we do: did someone touch the fake credential I planted? They do it well, and we don't compete with them on the perimeter use-case.

The difference is the layer. Honeytoken services fire when the token is used against the issuing service (a fake AWS key gets exercised against IAM, a fake API token hits a webhook, a DNS canary gets resolved). They sit on the network and watch for the call. They have no view into encrypted-at-rest storage and they don't know about cryptographic deniability.

deny.sh tripwires fire when the decoy is recovered from a decrypt call against our endpoint. We see the controlData parameter (controlData-kind tripwire) before decryption runs and we see the recovered plaintext (plaintext-kind tripwire) after it runs. The match happens inside the deniable-encryption substrate, where the attacker has already committed to decrypting. Honeytoken services can't sit there because the substrate is ours.

The use-cases are complementary. Plant a Thinkst Canary in your S3 bucket for perimeter alerting. Use deny.sh tripwires for the moment a decoy plaintext is recovered from a deniable-encrypted credential vault. Different layers, different alerts, different attacker phases.

agent deception / credential brokers

AgentShield, honeytools, credential proxies: the tool interface vs the secret itself.

A newer class of defence targets the same problem deny.sh was built for: a tool-using LLM agent that gets talked into leaking its own credentials via prompt injection. Two patterns dominate. Agent deception frameworks (for example AgentShield, a 2026 research framework) plant traps inside the agent's tool interface, fake tools whose invocation signals compromise, honeytokens that should never appear in legitimate traffic, and allowlisted-parameter checks. Credential brokers / proxies (the agent never holds the secret pattern) keep the real key at a network boundary and resolve it on the agent's behalf, so a compromised agent has nothing in context to exfiltrate.

Both are good ideas and we don't compete with either head-on. They operate at the interface and the network: detect a misused tool, or keep the secret out of the model's reach in the first place. deny.sh operates one layer down, at the secret itself. The credential is stored as a deniable ciphertext, so the value the agent can resolve and disclose is already a believable decoy, and recovering it fires a tripwire from inside the encryption substrate.

That difference matters when prevention fails open, which it does: an over-scoped tool, a path-traversal, a misconfigured proxy, a future capability the allowlist didn't anticipate. A broker reduces the odds the live key is ever in context; it has no answer for the day it is. A honeytool detects an agent reaching for a fake tool; it says nothing about the agent reading a real secret store aloud. deny.sh makes the disclosed secret survivable (the leak is a decoy) and detectable (the decrypt pages your on-call) regardless of how the agent was compromised. Run a broker and a honeytool if you have them; put deny.sh underneath both as the substrate that holds when they don't.

honest scope

What deny.sh is not.

An honest comparison cuts both ways. A few things to be clear about:

  • Not a full-disk encryption tool. Use VeraCrypt or BitLocker or LUKS for that, optionally on top of a deny.sh-encrypted file.
  • Not a messaging protocol. Signal and OTR cover live conversation deniability. We cover stored data.
  • Not protection against an adversary who can compel you to decrypt and observe whether you do. Cryptographic deniability defends against ciphertext leak, not against being watched while you type a password. See threat model.
  • Not externally audited yet. The construction is published in the cryptographic write-up with a proof sketch, and the SDKs ship full byte-compatibility test vectors across four languages. Independent audit is on the roadmap.
try it

See it work.

The comparison is nice but the proof is better. Try the demo or encrypt something right now.