Implementing End-to-End Encryption for Messaging
Overview
End-to-end encryption (E2EE) ensures that only the communicating parties can read messages, with no intermediary (including the server) able to decrypt them. This skill implements a simplified version of the Signal Protocol's Double Ratchet algorithm, using X25519 for key exchange, HKDF for key derivation, and AES-256-GCM for message encryption.
When to Use
Trigger phrases:
"implementing end to end encryption for messaging"
"End-to-end encryption (E2EE) ensures that only the communicating parties can rea"
When deploying or configuring implementing end to end encryption for messaging capabilities in your environment
When establishing security controls aligned to compliance requirements
When building or improving security architecture for this domain
When conducting security assessments that require this implementation
Prerequisites
- Familiarity with cryptography concepts and tools
- Access to a test or lab environment for safe execution
- Python 3.8+ with required dependencies installed
- Appropriate authorization for any testing activities
Objectives
- Implement X25519 Diffie-Hellman key exchange for session establishment
- Build the Double Ratchet key management algorithm
- Encrypt and decrypt messages with per-message keys
- Implement forward secrecy (compromise of current key does not reveal past messages)
- Handle out-of-order message delivery
- Implement key agreement using X3DH (Extended Triple Diffie-Hellman)
Key Concepts
This section covers key concepts for implementing end to end encryption for messaging.
- Ensure all prerequisites are met before proceeding
- Follow the documented workflow steps in sequence
- Record results and any anomalies encountered during this phase
Signal Protocol Components
| Component | Purpose | Algorithm |
|---|---|---|
| X3DH | Initial key agreement | X25519 |
| Double Ratchet | Ongoing key management | X25519 + HKDF + AES-GCM |
| Sending Chain | Per-message encryption keys | HMAC-SHA256 chain |
| Receiving Chain | Per-message decryption keys | HMAC-SHA256 chain |
| Root Chain | Derives new chain keys on DH ratchet | HKDF |
Forward Secrecy
Each message uses a unique encryption key derived from a ratcheting chain. After a key is used, it is deleted, ensuring that compromise of the current state does not reveal previously sent/received messages.
Security Considerations
- Delete message keys immediately after decryption
- Implement message ordering and replay protection
- Use authenticated encryption (AES-GCM) for all messages
- Protect identity keys with device-level security
- Verify identity keys out-of-band (safety numbers)
Validation Criteria
- X25519 key exchange produces shared secret
- Messages encrypt and decrypt correctly between two parties
- Different messages produce different ciphertexts
- Forward secrecy: old keys cannot decrypt new messages
- Out-of-order messages can be decrypted
- Tampered messages are rejected by authentication
When NOT to Use
- You need to test the implementation (use performing-* skills)
- Task is about configuring existing tools (use configuring-* skills)
- You need to analyze security events (use analyzing-* skills)
- Task is about building detection rules (use building-* skills)
- You don't have access to the target environment
- Task requires vendor-specific expertise (consult vendor docs)
Red Flags
- Performing actions without explicit written authorization from the asset owner
- Testing against production systems without a defined scope and rules of engagement
- Sharing sensitive findings or credentials in unencrypted communications
- Failing to properly scope and contain the assessment before starting
Verification
- All steps executed successfully against a test environment before production use
- Output documented with screenshots or logs demonstrating expected behavior
- Results validated against known-good baselines or reference implementations
- Documentation complete enough for another analyst to reproduce findings
Process
# Example: IOC detection
import re
IOC_PATTERNS = {
"ip": r"\b(?:\d{1,3}\.){3}\d{1,3}\b",
"domain": r"\b[a-z0-9-]+\.[a-z]{2,}\b",
"hash_md5": r"\b[a-f0-9]{32}\b",
"hash_sha256": r"\b[a-f0-9]{64}\b",
}
def extract_iocs(text: str) -> dict:
return {k: re.findall(v, text) for k, v in IOC_PATTERNS.items()}
- Analyze the task requirements
- Apply domain expertise
- Verify output quality
Anti-Rationalization Table
| Rationalization | Reality |
|---|---|
| "We are too small to be targeted" | Automated attacks target everyone. Size does not matter. |
| "Security slows us down" | A breach slows you down 100x more. Build security in from the start. |
| "We will fix it after launch" | Vulnerabilities in production are exploited within hours. Fix before deploy. |