Pages
Contents
Chat Crypto – Concept
Status: CONCEPT · Erstellt April 2026 Übergeordnet:
TOOL_chat_roadmap.mdVerwandt:TOOL_chat_concept-identity.md,TOOL_chat_concept-device.mdVerwandt:TOOL_chat_concept-message.md,@xpulse/crypto
Grundsätze
Privacy First – kein Server sieht jemals Nachrichteninhalte. Vertrauen durch Verifikation – nicht durch Versprechen. Transparenz – was der Peer sieht ist dokumentiert und bewusst entschieden.
Warum ein eigenes Konzept?
Kryptographie zieht sich durch alle Teile von xPulse Chat – Identität, Nachrichten, Devices, Sync. Dieses Konzept legt fest:
- Welche Schlüssel es gibt und wofür
- Was der Peer sieht und was nicht
- Wie Nachrichten verschlüsselt und signiert werden
- Wie Verifikation funktioniert
Schlüssel-Übersicht
| Pro User: |
| userId = SHA-256(userPublicKey) – öffentlich, stabil |
| userPublicKey = öffentlich – Peers kennen ihn |
| userPrivateKey = geheim – verlässt nie das Gerät |
| Pro Gerät: |
| clientId = SHA-256(clientPublicKey) – öffentlich, gerätegebunden |
| clientPublicKey = öffentlich – Peers kennen ihn |
| clientPrivateKey = geheim – verlässt nie das Gerät |
Was der Peer sieht
| Peer sieht: userId → wer du bist |
| userPublicKey → zum Verifizieren deiner Nachrichten |
| Peer sieht NICHT: clientId → welches Gerät |
| clientPublicKey → Geräte-Detail |
| privateKeys → niemals |
| Anzahl Geräte → intern |
Der userPublicKey ist by Design öffentlich – genau wie bei SSH.
Jeder mit dem du chattest kennt ihn. Das ist gewollt und notwendig
für E2EE Verifikation.
Nachrichten-Verschlüsselung (E2EE)
Nachrichten werden Ende-zu-Ende verschlüsselt über den WebRTC DataChannel.
| Sender → |
| Nachricht mit AES-GCM verschlüsseln |
| Schlüssel = ECDH(senderPrivateKey, receiverPublicKey) |
| → verschlüsselte Nachricht über DataChannel |
| Empfänger → |
| Schlüssel = ECDH(receiverPrivateKey, senderPublicKey) |
| → entschlüsseln → Klartext |
Kein Server sieht jemals den Inhalt – die Verschlüsselung passiert ausschließlich zwischen den zwei Peers.
Message-Signing
Jede Nachricht wird mit dem userPrivateKey des Senders signiert.
Der Empfänger verifiziert mit dem userPublicKey des Senders.
| Sender → |
| Nachricht erstellen |
| Signatur = (message, userPrivateKey) |
| → { ...message, signature } über DataChannel |
| Empfänger → |
| (message, signature, senderPublicKey) |
| OK → Nachricht ist authentisch ✅ |
| NOK → Nachricht verwerfen ❌ |
Was Message-Signing verhindert:
- Niemand kann Nachrichten fälschen – nicht mal ein Man-in-the-Middle
- Nachträglich veränderte Nachrichten werden erkannt
- Beim Sync: importierte Messages können auf Echtheit geprüft werden
signature in der Message-Struktur:
| meta: { |
| receivedAt: Number, |
| viewedAt: Number, |
| signature: String, // Base64 – Signatur der Nachricht |
| } |
Verifikation beim Sync
Beim Sync kommen Messages vom Peer – der Comparator prüft die Signatur bevor eine Message gemergt wird:
| Message kommt rein → |
| signature vorhanden? → |
| (message, signature, senderPublicKey) → |
| OK → normal weiter (Graveyard, Duplikat, Merge) |
| NOK → Message verwerfen, warn loggen |
| keine signature (v0 migriert) → |
| akzeptieren – Migration hat keine Signaturen |
Schlüssel-Austausch beim Pairing
Beim Chat-Pairing und Device-Pairing tauschen beide Peers ihre
userPublicKeys aus:
| Pairing → |
| A sendet userPublicKey → B speichert für A |
| B sendet userPublicKey → A speichert für B |
| → beide können ab jetzt Nachrichten verschlüsseln + verifizieren |
Der userPublicKey wird lokal gespeichert:
| xpulse_chat_{userId}_peer_{peerId}_public_key |
localStorage – Crypto Keys
| // User-Keypair |
| xpulse_identity_{userId}_public_key ← öffentlich |
| xpulse_identity_{userId}_private_key ← AES-GCM verschlüsselt mit PBKDF2(pw + salt) |
| xpulse_identity_{userId}_salt ← Salt für PBKDF2 |
| // Client-Keypair |
| xpulse_identity_client_public_key ← öffentlich |
| xpulse_identity_client_private_key ← AES-GCM verschlüsselt |
| // Bekannte Peer Public Keys |
| xpulse_chat_{userId}_peer_{peerId}_public_key ← Peer's userPublicKey |
Algorithmen
| Zweck | Algorithmus | Hinweis |
|---|---|---|
| Keypair Generierung | Ed25519 (Fallback: ECDSA P-256) | Identity + Signing |
| Schlüsselaustausch | ECDH | Nachrichten-Verschlüsselung |
| Nachrichten-Verschlüsselung | AES-GCM | via @xpulse/crypto |
| Schlüsselableitung | PBKDF2 | Passwort → Encryption Key |
| Hashing | SHA-256 | userId + clientId Ableitung |
| Signing | Ed25519 (Fallback: ECDSA P-256) | Message-Signatur |
Offene Punkte
| Thema | Stand |
|---|---|
| Key-Rotation – Keypair erneuern ohne userId zu ändern | TBD – komplex, später |
| Peer Public Key Verifikation out-of-band (z.B. QR-Vergleich) | TBD – Nice-to-have |