A forensics-resistant web chat service with end-to-end encryption using Diffie-Hellman key exchange. The system prioritizes privacy, forward secrecy, and resistance to forensic analysis.
- Initialize Node.js project structure
- Set up package.json with dependencies (ws, crypto modules)
- Create basic folder structure (src/server, src/client, public)
- Configure development environment and build tools
- Set up basic HTML/CSS structure for client interface
- Create basic WebSocket server using
wslibrary - Implement room management system (join/leave rooms)
- Add connection handling and client tracking
- Implement message routing between clients in same room
- Add basic error handling and connection cleanup
- Create HTML structure with Send and Receive areas
- Implement room join functionality, only two participants allowed Alice and Bob. Also in the webpage, put name 'Alice' in the UI. When the second user joins put name 'Bob' in his UI. Do not accept more participants.
- Add basic WebSocket client connection
- Create message input/output interface
- Add connection status indicators
- Once connected to a room the room id can't be changed by user, add a leave button and reload the page as a fresh session
Security Requirement: All client code must be self-contained and never downloaded from the server. Client files should be distributed separately for user verification and local execution.
- Implement DH key pair generation using Web Crypto API with both "deriveKey" and "deriveBits" usages for ECDH operations
- Create key exchange message format (pubkey type)
- Add public key transmission via WebSocket
- Implement shared secret derivation from DH exchange using deriveBits() to get raw key material for HKDF input, show in the UI of participants that the secret has been derived.
- Add key exchange state management
- Implement AES key derivation using HKDF/SHA-256 from ECDH raw key material, use deterministic salt for consistent key derivation between participants, update status in UI when AES key is ready
- Create AES-GCM encryption functions with encryptMessage() that generates random 12-byte IV and returns {ciphertext, iv} object
- Add IV/nonce generation for each message using crypto.getRandomValues() with 12 bytes for GCM mode
- Implement decryption functions with decryptMessage() that takes ciphertext, iv, and aesKey parameters
- Add encryption error handling with try-catch blocks and detailed error logging
- Update UI when encryption is ready: change placeholder text, button text to "Send Encrypted", show "Ready for encrypted messaging" status with pulse animation
- Integrate encryption into message sending: check keyExchangeCompleted && aesKey, encrypt with encryptMessage(), send as 'encrypted_message' type with ciphertext/iv arrays and sender role
- Implement encrypted message format with server relay: ciphertext + IV as byte arrays, sender identification, server broadcasts to room excluding sender
- Default encrypted display with individual toggle: messages show encrypted by default (globalShowPlaintext=false), each message has lock/unlock icon (🔒/🔓) in message header beside sender name, click toggles between hex preview and plaintext
- Individual message encryption toggle: both sent and received messages have clickable lock icons, encrypted text shows as "🔒 [hex20bytes...]", stores encryptedData and plaintextContent on messageDiv DOM element
- Global lock/unlock all button: positioned below security status outside scrolling area, button text shows action to perform ("🔓 Unlock All" when locked, "🔒 Lock All" when unlocked), applies to all messages with encryption data
- Message structure with encryption: message header contains sender name and lock icon, message content shows encrypted hex or plaintext based on state, auto-scroll with multiple timing attempts for visibility
- ENHANCED SECURITY: Updated lock behavior to hold-to-view mode: messages display encrypted ciphertext by default, individual lock icons require holding down (mousedown/touchstart) to temporarily show plaintext, global "Hold to Show All" button works similarly - all messages return to encrypted state when released for maximum security
- Hold-to-View Security Model: Implemented enhanced security where encrypted messages are displayed as ciphertext by default with no persistent plaintext visibility
- Individual Message Security: Each message lock icon (🔒) requires active holding (mouse/touch) to temporarily reveal plaintext - releases immediately when pressure stops
- Global Message Security: "Hold to Show All" button (🔒 Hold to Show All) applies hold-to-view behavior to all encrypted messages simultaneously
- Multi-Platform Support: Added both mouse events (mousedown/mouseup/mouseleave) and touch events (touchstart/touchend) for mobile compatibility
- Forensic Resistance: Enhanced forensic resistance by eliminating persistent plaintext display - messages automatically return to encrypted state without user action
- UI/UX Security: Updated button labels and tooltips to clearly indicate hold-to-view functionality, preventing accidental plaintext exposure
- Import BIP39 English wordlist (2048 words) into client code
- Create wordlist validation and lookup functions
- Implement bit-to-word mapping functions (11 bits per word)
- Add word-to-index conversion for verification
- Test wordlist integrity and completeness
- Convert BIP39 wordlist to JavaScript array format (bip39.js) for client-side loading
- Fix wordlist loading issues with server security restrictions
- Implement public key ordering function (canonical order for consistency)
- Create SHA-256 hash function for combined public keys:
hash = SHA-256(ordered(pubkeyA, pubkeyB)) - Extract first N×11 bits from hash (default N=5 for 55-bit security)
- Map extracted bits to BIP39 words using bit slicing
- Generate human-readable authcode (e.g., "abandon ability able about above")
- Add fingerprint computation after successful key exchange
- Display Alice's 5-word authcode in UI with copy-to-clipboard functionality
- Create verification input field for Bob to enter received authcode
- Implement string comparison for authcode verification
- Add visual feedback for successful/failed verification
- Block message sending until authentication is complete
- Replace Bob's manual input with visual comparison and Confirm/Reject buttons
- Implement encrypted ACK/NACK system using AES key for secure verification feedback
- Add bidirectional verification confirmation between Alice and Bob
- Design authentication dialog/modal for fingerprint display
- Add "Copy Authcode" button for Alice to share via OOB channel
- Create "Enter Authcode" input field for Bob with paste functionality
- Implement "Verify" button that compares computed vs received authcode
- Add clear success/failure indicators with appropriate messaging
- Show security status: "Verified" vs "Unverified" in connection status
- Redesign Bob's UI to show computed authcode with Confirm/Reject buttons
- Remove manual input field to eliminate user errors and improve UX
- Add waiting indicators for Alice during Bob's verification process
- Implement enhanced security warnings for MITM attack detection
- Add
isAuthenticatedflag to track verification status - Prevent message encryption/sending until authentication completes
- Update security status indicators to show authentication state
- Add re-verification mechanism if key exchange resets
- Implement authentication timeout and retry mechanisms
- Store authentication state only in memory (no persistence)
- Add guidance text explaining OOB channel requirement
- Create user instructions for secure authcode sharing (SMS, voice, in-person)
- Implement QR code generation for authcode sharing (optional)
- Enforce mandatory MITM protection verification (skip option removed for security)
- Document OOB channel security requirements and recommendations
- Encrypted Verification Protocol: Implement ACK/NACK system using established AES key
- Enhanced MITM Detection: Use encrypted confirmation to prevent verification spoofing
- Secure Feedback Loop: Ensure Alice receives authentic verification results from Bob
- Remove Skip Option: Eliminate security bypass to enforce mandatory verification
- Improved Error Handling: Add comprehensive error messages and security warnings
- Simplified User Flow: Replace manual input with visual comparison for better UX
- Create intuitive room creation/joining flow
- Add visual indicators for encryption status
- Implement typing indicators (encrypted)
- Add message delivery status display
- Create responsive design for mobile devices
- Add key exchange completion indicators
- Implement connection security status
- Create visual encryption confirmations
- Add session security warnings
- Implement fingerprint display (optional)
- Add comprehensive error messages
- Implement connection failure handling
- Create key exchange failure recovery
- Add user guidance for security features
- Implement graceful degradation
- Test cryptographic functions
- Validate key exchange mechanisms
- Test message encryption/decryption
- Verify memory management
- Test WebSocket communication
- Test end-to-end message flow
- Validate multi-client scenarios
- Test room management functionality
- Verify security properties
- Test error scenarios
- Penetration testing for key exchange
- Validate forward secrecy implementation
- Test memory forensics resistance
- Verify no data persistence
- Test MITM attack resistance
- Create production build configuration
- Implement environment-specific settings
- Add performance optimizations
- Create deployment scripts
- Set up monitoring and logging (minimal)
- Create user documentation
- Write security analysis document
- Document API and message formats
- Create deployment guide
- Add troubleshooting guide
- QR code integration for room sharing
- Public key fingerprint verification
- Multi-device session handling
- Group messaging preparation (MLS)
- Tor/onion service support
- Technology: Node.js with
wslibrary - Responsibilities: Message routing, room management, connection handling
- Security: Stateless operation, no message storage, minimal metadata
- Performance: Handle multiple concurrent rooms and connections
- Technology: Vanilla JavaScript with Web Crypto API
- Responsibilities: UI, encryption/decryption, key management
- Security: No persistent storage, secure memory handling
- Compatibility: Modern browsers with Web Crypto API support
- Key Exchange: ECDH over P-256 or X25519
- Encryption: AES-GCM with HKDF-derived keys
- Security Properties: Forward secrecy, ephemeral keys, secure random generation
- Implementation: Web Crypto API for client, Node.js crypto for server
- True end-to-end encryption (server cannot decrypt)
- Forward secrecy through ephemeral keys
- No persistent storage of messages or keys
- Resistance to forensic analysis
- Protection against MITM attacks
- Two users can join the same room
- Successful DH key exchange
- Encrypted message exchange
- Message delivery confirmation
- Clean session termination
- No user registration or identity required
- Minimal metadata exposure
- No server-side message storage
- No client-side message persistence
- Anonymous communication support
- Browser compatibility: Use progressive enhancement and fallbacks
- Key exchange failures: Implement retry mechanisms and error recovery
- Memory leaks: Implement proper cleanup and monitoring
- Performance issues: Optimize crypto operations and message handling
- MITM attacks: Optional fingerprint verification system
- Memory forensics: Secure memory clearing and minimal data lifetime
- Side-channel attacks: Use timing-safe operations where possible
- Implementation bugs: Comprehensive testing and security review
- Phase 1: 2-3 weeks (Foundation)
- Phase 2: 3-4 weeks (Cryptography)
- Phase 3: 2-3 weeks (Security)
- Phase 4: 2-3 weeks (UI/UX)
- Phase 5: 2-3 weeks (Testing)
- Phase 6: 1-2 weeks (Deployment)
Total Estimated Time: 12-18 weeks
ws(WebSocket server)- Web Crypto API (browser support)
- Node.js
cryptomodule
- Modern browsers with Web Crypto API support
- WebSocket support
- ES6+ JavaScript support
- Node.js runtime environment
- Optional: Reverse proxy for production
- Optional: Tor support for enhanced anonymity