First-party web encryption format
This document specifies the format written by the first-party AnonPaste web app. It is a compatibility specification for the web client and backend, not a claim that every paste field or every AnonPaste API is encrypted.
Scope and threat boundary
Section titled “Scope and threat boundary”Encrypted and Secret-link modes encrypt selected text values and file bytes in the browser before upload. The server stores and returns the resulting ciphertext.
The envelope does not hide everything required to operate a paste. Depending on the workflow, the server still receives fields such as the paste reference, encrypted-mode choice, encryption version, expiry, burn setting, content/file type, ordering and size information, account or anonymous authorization, and request metadata used for delivery, abuse prevention, and service operation.
Encryption does not prevent a recipient from copying, saving, photographing, or forwarding plaintext after decryption. AnonPaste cannot recover a lost Secret-link key or password.
Key and lookup derivation
Section titled “Key and lookup derivation”Let secret be either:
- the password supplied by the creator, or
- a random Secret-link value generated by the web client.
The first-party web client derives:
encryption_key = SHA-256(UTF-8(secret)) // 32 raw bytes, represented as lowercase hex internallylookup_key = SHA-256(hex(encryption_key)) // lowercase hex stringencryption_key remains in the browser and is used with AES-256-GCM. lookup_key is sent where the API needs a stable protected-paste lookup credential. These values are purpose-separated by the second hash, but the password path is still only a direct SHA-256 derivation: use a strong, unique passphrase.
Secret-link mode
Section titled “Secret-link mode”The share reference is formatted as:
<paste-reference>#<secret>The URL fragment beginning with # is not sent in the HTTP request by normal browsers. The recipient must receive the complete link. The browser derives both keys locally from the fragment secret.
Password mode
Section titled “Password mode”The password is not included in the share URL. The creator must send it separately. The viewer derives the same keys after the recipient enters the password.
Version 2 text envelope
Section titled “Version 2 text envelope”New encrypted text values use:
algorithm AES-256-GCMkey encryption_key (32 bytes)IV 12 random bytes per text valueauthentication 128-bit GCM tagAAD UTF-8("anonpaste:v2:text")plaintext raw UTF-8 text; no legacy pre-encryption compressionSerialized form:
apenc:2:text:<base64(iv)>:<base64(ciphertext || tag)>Each encrypted text value gets a fresh random IV. A version 2 record that does not contain a valid version 2 envelope fails decryption; it does not fall back to CBC.
Version 2 file envelope
Section titled “Version 2 file envelope”New encrypted files use:
algorithm AES-256-GCMkey encryption_key (32 bytes)IV 12 random bytes per fileauthentication 128-bit GCM tagAAD UTF-8("anonpaste:v2:file")plaintext original file bytesBinary serialized form:
offset length value0 7 ASCII "APENC2F"7 12 IV19 rest ciphertext || 16-byte GCM tagThe encrypted blob keeps the original MIME type for delivery. MIME type, filename, size, and other file-management fields are therefore not implied to be encrypted by this byte envelope.
Persistence and lifecycle
Section titled “Persistence and lifecycle”The web client writes encryptionVersion: 2 for new encrypted full and Quick pastes. The backend validates and persists that version with the paste record.
- Expiry makes the stored paste unavailable after its configured time.
- Burn after view removes the stored paste after the successful retrieval defined by that workflow.
- Deletion removes the server-side record through the supported owner or management path.
- None of these operations can revoke plaintext or ciphertext already copied, cached, downloaded, or forwarded elsewhere.
Quick-paste preview integrations do not receive password-protected or burn-after-view content. Full-paste link-preview bots receive placeholder content for burn-after-view pastes instead of consuming the permitted read. Unknown third-party scanners are outside this guarantee.
Version 1 compatibility
Section titled “Version 1 compatibility”Existing version 1 web content remains decryptable. It used AES-256-CBC, PKCS#7 padding, the SHA-256-derived encryption key, and the historical fixed IV:
be410fea41df7162a679875ec131cf2cVersion 1 is decrypt-only in the current first-party web path. New encrypted writes use version 2. Version selection comes from the persisted encryption version and the v2 envelope marker, not a paste-ID date cutoff.
Deterministic test vectors
Section titled “Deterministic test vectors”These vectors use a fixed IV only to make independent implementations testable. Production encryption must generate a fresh unpredictable 12-byte IV for every value or file.
secret: correct horse battery stapleencryption_key: c4bbcb1fbec99d65bf59d85c8cb62ee2db963f0fe106f483d9afa73bd4e39a8aIV (hex): 000102030405060708090a0bAAD: anonpaste:v2:textplaintext UTF-8: AnonPaste v2 test vectorciphertext+tag: VqOzPTzMkZ6utM7qZd7xzhJSlteSNXgIlprOJFcUT2swullCIFyuMA==envelope: apenc:2:text:AAECAwQFBgcICQoL:VqOzPTzMkZ6utM7qZd7xzhJSlteSNXgIlprOJFcUT2swullCIFyuMA==secret: correct horse battery stapleencryption_key: c4bbcb1fbec99d65bf59d85c8cb62ee2db963f0fe106f483d9afa73bd4e39a8aIV (hex): 000102030405060708090a0bAAD: anonpaste:v2:fileplaintext hex: 00010203feffciphertext+tag: F8zeUJJSrcIia+gfbbweAYw85xi2vQ==envelope hex: 4150454e433246000102030405060708090a0b17ccde509252adc2226be81f6dbc1e018c3ce718b6bdImplementation requirements
Section titled “Implementation requirements”- Reject malformed prefixes, IV lengths, authentication tags, and trailing text-envelope fields.
- Never reuse an IV with the same key.
- Authenticate the exact AAD string for the envelope type.
- Treat GCM authentication failure as a hard decryption error.
- Do not silently downgrade a record marked version 2.
- Keep keys out of logs, analytics, error reports, and server-rendered markup.