🇳🇱

How It Works

Technology and Security

Bixby encrypts your messages in the browser before they leave your device. The server never sees your message. Only encrypted data.

Zero-Knowledge

Your message is encrypted in your browser before being sent. The server only receives encrypted data and therefore cannot read your message. AES-GCM-256 encryption via Web Crypto API. Encryption happens client-side, plaintext never leaves device.

crypto.js JavaScript
async function encryptMessage(plaintext) { // Generate 256-bit key const key = await crypto.subtle.generateKey( { name: 'AES-GCM', length: 256 }, true, ['encrypt', 'decrypt'] ); // Random IV + encrypt (plaintext never leaves device) const iv = crypto.getRandomValues(new Uint8Array(12)); const encrypted = await crypto.subtle.encrypt( { name: 'AES-GCM', iv }, key, new TextEncoder().encode(plaintext) ); return { encrypted, key }; }

Key in URL

The decryption key is in the URL (after #). It's not sent to the server, which means the server cannot read your message. 256-bit AES-GCM key in URL fragment. Fragments are not sent in HTTP requests (RFC 3986).

app.js JavaScript
// Encrypt locally, send only encrypted blob to server const { encrypted, key } = await encryptMessage(message); const { id } = await fetch('/api/store', { method: 'POST', body: JSON.stringify({ encrypted }) }).then(r => r.json()); // Key in URL fragment - never sent to server (RFC 3986) const link = `https://bixby.nl/read#${id}__${key}`;

One-Time Access

After reading, the message is immediately deleted. Each link works only once. Atomic delete: file_get_contents() + unlink() in one operation. Prevents race conditions.

api/read.php PHP
$id = preg_replace('/[^a-f0-9]/', '', $_POST['id']); $path = "/messages/{$id}.json"; $data = json_decode(file_get_contents($path), true); // Delete immediately after reading (burn-on-read) unlink($path); echo json_encode(['encrypted' => $data['encrypted']]);

Technology

Encryption

Native browser encryption. No external libraries needed. AES-GCM-256, Web Crypto API. IV: 96-bit random. Authenticated encryption.

Backend

Simple PHP API. No database needed. PHP 8.3. File-based storage. TTL: configurable, 30-day fallback. Atomic delete operations.

Server

Fast, secure web server. Nginx 1.24 + PHP-FPM 8.3. SSL/TLS via Let's Encrypt. Security headers: CSP, HSTS.

Storage

Temporary files, automatically cleaned up after a maximum of 30 days. Encrypted blobs in /messages/. Cron cleanup. Direct access blocked (403).

Security

  • Encryption happens in your browser before data leaves your device
    AES-GCM-256, Web Crypto API. Plaintext never leaves device.
  • The server never sees your message
    Zero-knowledge: only encrypted blobs, no plaintext possible.
  • The key stays in the recipient's possession
    Key in URL fragment, not sent in HTTP requests.
  • The message is deleted immediately after reading
    Burn-on-read: atomic delete, no repeated access.
  • Automatic cleanup of unread messages
    Messages with an expiry time expire automatically. Other messages are cleaned up after 30 days.
  • No tracking or logging
    No tracking cookies, analytics, or content logging.

Transparency

All client-side code is inspectable. No minified JavaScript, no obfuscation. View the key files via the link below.

View source code

Verify it yourself

Enter a test message below. The demo follows the exact same steps as a real message, including the real API.

Privacy

No tracking, analytics or logging. No tracking cookies. No third-party scripts.

Privacy Policy

Hosted in the Netherlands 🇳🇱

Bixby is hosted on servers in the Netherlands. Your data stays within the EU and falls under Dutch privacy laws. Dutch datacenter, EU data residency, GDPR compliant.

← Return

Total notes served: 28 Messenger messages: 14