AES-GCM message encryption
Message text is encrypted with Apple CryptoKit AES.GCM. The API stores ciphertext, nonce, tag, and salt separately.
Security Resources
cryptoscreen is built around local encryption, PIN-gated opening, short-lived server rows, and explicit limits. This page explains what is protected, what the server stores, and where the trust boundary ends.
Security basics
The sender writes the note in the iPhone app. The app derives the content key locally from the link secret and six-digit PIN, encrypts the plaintext, and uploads only encrypted bytes plus the metadata needed to enforce expiry and PIN attempts.
The URL fragment after #s= carries the link secret. Browsers do not send that fragment to the Worker in normal HTTP requests, so the server receives the message id but not the decryption secret.
The PIN is not stored by cryptoscreen. The app sends a PIN proof so the Worker can decide whether to release the encrypted payload without learning the PIN or plaintext.
Message text is encrypted with Apple CryptoKit AES.GCM. The API stores ciphertext, nonce, tag, and salt separately.
The content key is derived from a 32-byte link secret, the normalized six-digit PIN, and a 16-byte per-message salt using HKDF-SHA256.
The online PIN proof uses a separate HKDF-SHA256 context and is stored by the Worker only after applying a server-side pepper.
Image attachments use a random 32-byte file key. The image is encrypted with that key, then the file key is encrypted with the message key.
Storage and deletion
Neon stores encrypted message bytes, nonce, tag, salt, read policy, expiry time, failed attempt count, and a server-peppered PIN verifier. Cloudflare R2 stores encrypted image object bytes when an image is attached.
User message rows delete after one successful read, after the third wrong PIN attempt, when the sender expires the message, or after 30 days if unopened. Encrypted attachment objects are removed after their one-time download or scheduled cleanup.
cryptoscreen keeps minimal delivery status so the app can show whether a sent message was consumed, expired, destroyed, or reported a screenshot event when reciprocal interaction status is enabled. That status does not include plaintext, image plaintext, PINs, link secrets, sender contacts, or recipient contacts.
Operational security
Message plaintext, raw image bytes, link secrets, PIN values, and one-time read behavior from routine server-side access or database-only compromise.
The sender and recipient devices are trusted while encrypting or reading, iOS CryptoKit behaves correctly, and the delivered app build has not been maliciously modified.
Screenshot and screen recording responses reduce accidental exposure. iOS reports screenshots after capture, and external cameras cannot be detected.
Compromised devices, malicious recipients, external cameras, phishing, social engineering, copied content after display, or link/PIN sharing with the wrong person.
Technical integrity
cryptoscreen does not promise magic disappearing text. It promises a narrower system: encrypt locally, avoid server plaintext, release encrypted payloads only after a correct PIN proof, consume normal links once, and be clear about the limits.