← 피드로
I built a zero-knowledge secret sharing tool. Text and files are encrypted in the browser with AES-GCM 256 before upload – the server only ever sees ciphertext.
The decryption key lives exclusively in the URL fragment (#k=…). URL fragments are never sent in HTTP requests (RFC 9110 §4.2.3), so Cloudflare Workers, D1, and R2 never see it – even in logs.
A few things I tried to do right:
- Single-use by default: Durable Objects handle atomic read→decrement→delete with blockConcurrencyWhile, no race conditions on concurrent requests
- Paranoid mode: returns not_found instead of expired/burned, no timing oracle
- Revoke endpoint: delete a drop before it’s read using a SHA-256’d token with constant-time comparison
- CLI: burnafter send / burnafter receive – full E2E from terminal, key never touches a browser – /security page with a live in-browser AES-GCM demo and a manual Node.js decryption snippet so you can verify without trusting me
Stack: Cloudflare Workers + D1 + R2 + Durable Objects. No third-party crypto libs.
Live: https://burnafterread.casablanque.com
Source: https://github.com/casablanque-code/burnafterread
Verify: https://burnafterread.casablanque.com/security
답글 남기기