← BACK TO SHINOBU
SECURITY & THREAT MODEL
Last updated: July 2026
128
BIT KEY
AES
256-GCM
0
DEPENDENCIES
DESIGN GOALS
- No accounts, no emails, no phone numbers — zero identity required
- All message content is end-to-end encrypted before leaving the device
- No message content is stored unencrypted on any server
- All data is ephemeral — it vanishes when you leave
- The server never sees plaintext messages or encryption keys
- Group rooms support up to 12 members with display names and unique colors
ENCRYPTION ARCHITECTURE
SHINOBU uses AES-256-GCM authenticated encryption with PBKDF2 (SHA-256) key derivation. A random 128-bit encryption key is generated on room creation using crypto.getRandomValues().
KEY SEPARATION MODEL
The room code (public identifier) and the encryption key (secret) are separate values. The room code is stored on the server and used to identify the room. The encryption key is stored only in your browser's URL fragment (#room=CODE&key=KEY) and localStorage — it is never sent to the server. In group rooms, all members share the same encryption key.
ENCRYPTION FLOW
1
KEY GENERATION -- Creator generates a random 128-bit key via crypto.getRandomValues()
2
KEY SHARING -- Key embedded in URL fragment (#room=CODE&key=KEY), never sent to server
3
ENCRYPT -- Sender encrypts each message with AES-256-GCM before transmission
4
TRANSMIT -- Ciphertext sent over TLS 1.3. Server sees only encrypted blobs
5
DECRYPT -- Receiver derives key via PBKDF2-SHA256, decrypts locally
SAFETY NUMBERS
All members in a room see the same 6-emoji safety number derived from the shared encryption key. If the numbers match, everyone is using the same key and no man-in-the-middle is present. Verify out-of-band (voice call, in person).
WHAT THE SERVER SEES
| Data |
Stored? |
Encrypted? |
| Room code |
Yes |
No — public identifier |
| Message text |
Yes |
Yes — AES-256-GCM |
| File attachments |
Yes |
Yes — AES-256-GCM |
| Encryption key |
No |
N/A — never sent |
| User identity |
No |
N/A — no accounts |
| Read receipts |
Yes |
No — boolean flag |
WHAT WE PROTECT AGAINST
HIGH
SERVER COMPROMISE
An attacker who gains full access to the server backend can read room codes, encrypted message blobs, and file attachments. They cannot decrypt message content without the encryption key, which is never stored server-side.
HIGH
NETWORK TAPPING
All communication uses HTTPS (TLS 1.3). Even if TLS is broken, the attacker only gets ciphertext. AES-256-GCM is considered quantum-resistant for the foreseeable future.
MEDIUM
KEY SHARING
The encryption key travels via URL fragment. Some applications may inadvertently expose fragments. The app recommends sharing the key through a separate channel for maximum security.
MEDIUM
SHARED DEVICE
Encryption keys are stored in localStorage. Anyone with access to the same browser can retrieve them. SHINOBU is designed for personal devices. The Panic Wipe feature (Ctrl+Shift+X) clears all stored keys instantly.
KNOWN LIMITATIONS
- No protection against screenshots or screen recording on the receiver's device
- Encryption keys are only as secure as the device storing them
- Link previews in messaging apps may expose the URL fragment
- Server-assisted delivery means the server handles encrypted message routing
ABUSE PREVENTION
- Group rooms limited to 12 members
- Timestamps rounded to the nearest minute to prevent timing analysis
ROOM CODE ENTROPY
AUTO-GENERATED CODES
Room codes: 12 characters from a 55-character alphabet = ~71 bits of entropy. Mailbox codes: 16 characters = ~94 bits of entropy. User-chosen codes must be at least 8 characters. Auto-generated codes are recommended for maximum security.
DATA DESTRUCTION
- Private Rooms: Self-destruct when both members leave. All data is deleted when the room is destroyed.
- Group Rooms: Self-destruct when the last member leaves. All data is deleted.
- Mailboxes: Auto-expire after a period of inactivity.
- Delete-after-read: Messages fade out visually, then are removed from the server.
- Panic Wipe: Ctrl+Shift+X destroys all local data, disconnects from server, and clears all encryption keys from localStorage. Server-side data remains encrypted until room expiry.
CRYPTO DETAILS
| Component |
Specification |
| Symmetric cipher |
AES-256-GCM |
| Key derivation |
PBKDF2-SHA256 |
| Key length |
256 bits (derived from 128-bit input) |
| Salt |
16 bytes, random per message |
| IV / nonce |
12 bytes, random per message |
| Random generation |
crypto.getRandomValues() |
| Transport |
TLS 1.3 |