Comprehensive security analysis of Secure P2P Messenger.
- Cryptographic Architecture
- Threat Model
- Security Features
- Attack Resistance
- Known Limitations
- Best Practices
- Vulnerability Disclosure
The messenger implements a multi-layer encryption scheme:
User A Server User B
│ │ │
│ ─── Access Code ────────────► │ ◄──── Access Code ───────── │
│ │ │
│ ◄── Ed25519 Identity ────────┤────── Ed25519 Identity ─────► │
│ │ │
│ ──────── X25519 ECDH Key Exchange (via server) ────────────► │
│ │ │
│ ◄────────── Shared Secret (AES-256-GCM) ──────────────────► │
│ │ │
│ ─── Encrypted Message ──────► │ ─── Encrypted Message ─────► │
│ (Server cannot decrypt) │ (Server cannot decrypt) │
Purpose: Derive deterministic public ID from access code
// Pseudocode
accessCode → SHA-256 → seed (32 bytes)
seed → Ed25519 KeyPair
publicKey → base64 → Public ID (visible to others)
privateKey → base64 → Private Key (stored locally)Properties:
- Deterministic: Same access code always generates same keys
- Multi-device: Use same code on multiple devices
- No server-side key storage
Purpose: Generate shared encryption key between two users
// Pseudocode
User A: privateKeyA + publicKeyB → sharedSecretAB
User B: privateKeyB + publicKeyA → sharedSecretAB
// Both arrive at same shared secret
sharedSecretAB → SHA-256 → AES-256 keyProperties:
- Perfect Forward Secrecy: Each session uses unique shared secret
- Elliptic Curve: 256-bit security (equivalent to 3072-bit RSA)
- Server cannot compute shared secret (zero-knowledge)
Purpose: Encrypt message content
Algorithm: AES-256 in GCM mode
- Key Size: 256 bits
- Nonce: 96 bits (random)
- MAC: 128 bits (authentication tag)
Properties:
- Authenticated Encryption: Integrity + confidentiality
- Resistant to tampering
- Nonce never reused (random generation)
Encryption Process:
plaintext + sharedKey + randomNonce → [ciphertext + MAC]
Decryption Process:
[ciphertext + MAC] + sharedKey → verify MAC → plaintext
-
Passive Network Monitoring
- ISP cannot read messages
- Government surveillance cannot decrypt
- DPI cannot extract content
-
Server Compromise
- Server admin cannot read messages
- Server breach doesn't expose message content
- Server logs only encrypted data
-
Man-in-the-Middle (MITM)
- Public key exchange verified via access code
- Each user verifies peer's public ID
- Server cannot impersonate users
-
Message Tampering
- AES-GCM MAC detects modifications
- Invalid MAC → message rejected
-
Replay Attacks
- Timestamp checking (messages older than 24h dropped)
- Nonce uniqueness prevents replay
-
Endpoint Compromise
- If device is hacked, messages are readable
- Keylogger can capture messages before encryption
- Mitigation: Device security (PIN, encryption, etc.)
-
Access Code Leakage
- If access code stolen, attacker gets same identity
- Mitigation: Keep code secret, emergency wipe feature
-
Traffic Analysis
- Server knows who talks to whom
- Server knows message timing/size
- Mitigation: Use Tor/VPN for metadata privacy
-
Screen Recording / Screenshots
- Visual access to device exposes messages
- Mitigation: Physical device security
What server KNOWS:
- User is online/offline
- Message routing (from → to)
- Message size and timestamp
What server CANNOT know:
- Message content (encrypted)
- User identity (only sees public key hash)
- Relationship between access code and public ID
Storage Format:
flutter_secure_storage (platform keychain)
├── contacts (encrypted JSON)
├── messages_<contactID> (encrypted JSON per contact)
├── public_key (base64)
├── private_key (base64)
└── access_code (stored for convenience)
Platform Security:
- Android: Android Keystore (hardware-backed on modern devices)
- Windows: Windows Credential Manager (DPAPI)
Server Storage:
pendingMessages[userID] = [
{encrypted_message_1},
{encrypted_message_2},
...
]
Properties:
- Messages stored encrypted (server cannot read)
- 24-hour TTL (automatic cleanup)
- Delivered on next connection
- Removed from server after delivery
Same Access Code = Same Identity:
Device A: code → keyPair A
Device B: code → keyPair A (identical!)
Advantages:
- Seamless multi-device login
- No device pairing needed
Risks:
- Access code compromise = all devices compromised
- Mitigation: Keep code extremely secure
Attack Scenario:
User A ──► Attacker ──► Server ──► User B
Defense:
- Public keys derived from access code (verifiable)
- Users can verify peer's Public ID out-of-band
- Server cannot modify public keys (deterministic from code)
Recommendation:
- Verify peer's Public ID in person or via trusted channel
- Compare first 8 characters of Public ID
Attack Scenario:
- Attacker gains root access to VPS
- Reads all server memory and logs
What attacker gets:
- List of online users (public IDs)
- Encrypted message queue
- Message routing metadata
What attacker CANNOT get:
- Message plaintext (encrypted E2EE)
- Access codes (not stored on server)
- Private keys (stored only on clients)
Attack Scenario:
- Attacker captures encrypted message
- Resends it later to recipient
Defense:
- Nonce randomness (different ciphertext each time)
- Timestamp checking (24-hour window)
- Application-level deduplication
Attack Scenario:
- Attacker floods server with connections
Mitigation:
- Access code validation (attackers need valid codes)
- Rate limiting at network level (firewall)
- Small user base (10-50) makes DoS less attractive
Recommendation:
- Use fail2ban or similar
- Limit connections per IP
Attack Scenario:
- Adversary monitors network traffic
- Learns who talks to whom, when, how much
Current Status: NOT PROTECTED
- Server sees routing metadata
- ISP sees traffic to/from server IP
Mitigation Options:
- Use VPN/Tor for client connections
- Add dummy traffic (cover traffic)
- Implement onion routing (future work)
Problem: Server knows communication patterns
Impact: Medium
- Who talks to whom
- Message frequency
- Online/offline times
Mitigation:
- Use Tor/VPN
- Traffic padding (future)
Problem: Same key pair used for all sessions
Impact: Medium
- If access code compromised, all past messages decryptable (if captured)
Mitigation:
- Rotate access codes periodically
- Future: Implement Signal Protocol (Double Ratchet)
Problem: Single point of failure
Impact: High if compromised
- Access code leaks → full account access
Mitigation:
- Keep code extremely secure
- Emergency wipe feature
- Strong random codes only
Problem: No cryptographic signature proving sender identity
Impact: Low (trust model assumes server honesty)
- Malicious server could impersonate users theoretically
Future Improvement:
- Sign messages with Ed25519 private key
Problem: Voice/video calls rely on Agora SDK
Security Status:
- Agora uses E2EE for calls
- But Agora is closed-source
- Trust in Agora required
Mitigation:
- Calls use separate encryption layer
- Future: WebRTC self-hosted (no external)
-
Access Code Security:
- ✅ Store code in password manager
- ✅ Never share code via insecure channels
- ❌ Don't write code on paper/notes app
- ❌ Don't share code on social media
-
Device Security:
- ✅ Enable device lock (PIN/biometric)
- ✅ Keep OS updated
- ✅ Use full disk encryption
- ❌ Don't root/jailbreak device
-
Network Security:
- ✅ Use VPN in untrusted networks
- ✅ Avoid public WiFi for sensitive chats
- ❌ Don't disable HTTPS/SSL verification
-
Emergency Procedures:
- ✅ Use "Emergency Wipe" if device lost
- ✅ Contact admin for new access code
- ❌ Don't try to "recover" lost code (impossible)
-
Access Code Generation:
# Strong random codes only! openssl rand -base64 20 | tr -d '/+=' | head -c 24 | \ sed 's/\(....\)/SECURE-\1-/g' | sed 's/-$//'
- ✅ Use cryptographically secure random
- ❌ Don't use predictable patterns
- ❌ Don't reuse codes
-
Server Hardening:
# Firewall sudo ufw default deny incoming sudo ufw allow 22 # SSH sudo ufw allow 9090 # Messenger # Fail2ban sudo apt install fail2ban # Auto-updates sudo apt install unattended-upgrades
-
Access Code Management:
- ✅ Store codes in encrypted database
- ✅ Distribute via secure channel (in-person, Signal, etc.)
- ❌ Never commit codes to Git
- ❌ Never send codes via unencrypted email
-
Monitoring:
# Regular log checks sudo journalctl -u messenger-server -f # Watch for suspicious activity grep "Invalid" /var/log/messenger.log
If you discover a security vulnerability, please:
- DO NOT open a public GitHub issue
- Email: [Your security email here]
- Include:
- Vulnerability description
- Steps to reproduce
- Potential impact
- Suggested fix (if any)
- 24 hours: Initial response
- 7 days: Assessment and severity rating
- 30 days: Patch development and testing
- Public disclosure: After patch released (coordinated disclosure)
- Security fixes released as patches
- Critical issues: Immediate notification to all users
- Minor issues: Included in regular updates
- ✅ Code review completed (December 2024)
- ⏳ Independent security audit: Pending
- ⏳ Penetration testing: Pending
No critical vulnerabilities currently known.
-
Implement Perfect Forward Secrecy
- Signal Protocol / Double Ratchet
- Rotate keys per session
-
Add Message Signatures
- Sign messages with Ed25519
- Prevent server impersonation
-
Self-Hosted Calls
- Replace Agora with WebRTC
- Full control over call infrastructure
-
Metadata Protection
- Add traffic padding
- Implement mixing (delay messages)
- ✅ No personal data collection (no phone/email)
- ✅ User controls all data (local storage)
- ✅ Right to erasure (emergency wipe)
- ✅ Data minimization (only encrypted data on server)
- Client: User controls (delete anytime)
- Server: 24 hours maximum (offline messages only)
Secure P2P Messenger provides strong end-to-end encryption suitable for:
- Private team communication
- Sensitive business discussions
- Personal messaging with privacy focus
Strengths:
- ✅ Military-grade encryption (X25519 + AES-256-GCM)
- ✅ Zero-knowledge server
- ✅ No phone number / email required
- ✅ Multi-device support
Limitations:
⚠️ Metadata not hidden⚠️ Access code = single point of failure⚠️ No PFS (yet)
Recommendation: Suitable for groups requiring privacy but not for life-threatening scenarios (activists in authoritarian regimes). For maximum security, combine with VPN/Tor.
Questions? GitHub Discussions
Made with ❤️ by sssilverhand