Die Version Ad Nihilum 0.4.3 ist erschienen – ein minimalistischer Dienst zum Austausch von verschlüsselten Nachrichten nach dem Prinzip „gelesen – verbrannt“, der in erster Linie für Self-Hosting ausgelegt ist.
Der Server fungiert lediglich als stummes Speichermedium. Die Verschlüsselung und Entschlüsselung erfolgt ausschließlich auf der Client-Seite, im Browser (über AES-GCM).
Besonderheiten
- lokale Verschlüsselung und Entschlüsselung, der Server sieht niemals den Schlüssel;
- Unterstützung einer zusätzlichen Schicht der Verschlüsselung mittels eines Passworts, über das (1) der Server keine Kenntnis erlangen kann, (2) das nicht über den übertragenen Link ermittelbar ist;
- Das Projekt umfasst etwa 2200 Zeilen Server-Code in C und 600 Zeilen Client-Code in JS, was die Überprüfung erleichtert;
- Ad Nihilum ist ausschließlich von libmicrohttpd abhängig. Für die Generierung von QR-Codes wird eine modifizierte Version von QRCode.js bereitgestellt;
- Eine Anleitung zum schnellen Aufsetzen des lokalen Dienstes ohne externe IP liegt bei;
- Ad Nihilum läuft auch auf Android, ein entsprechendes Skript für den Build in Termux ist beigefügt;
- einzelner Thread und synchroner Server.
Änderungen
Umfangreiches Redesign
- Die Seiten zum Senden und Empfangen von Nachrichten wurden getrennt, der entsprechende Client-Code.
- Das Design wurde generell stark verändert und angepasst, um den Wünschen der Benutzer gerecht zu werden.
- „Einfach“ und lokale Clients:
- Kundenseiten können lokal gespeichert und über file:// verwendet werden.
Browser-Richtlinien
- CSP wurde implementiert, um XSS zu bekämpfen;
- der Server sendet HSTS.
Weitere Änderungen
- Das Projekt wurde von Epha-ots umbenannt;
- Die Domain adnihilum.net wurde gekauft;
- TLS wird mit Let’s Encrypt bereitgestellt, das sollte man im Hinterkopf behalten (kein Geld vorhanden);
- Die Arbeit mit Dateien wurde vereinfacht;
- Übergang zu Fat-Pointern;
- Kleine Bugs wurden behoben;
- Auto-jsminify und Zusammenstellung der Client-Dateien während des Builds mit CMake.
Überblick über das Protokoll
Drei zufällige Werte generieren: Schlüssel K, Initialisierungsvektor N und Salt O. K — 256 Bit, N — 96 Bit, O — 128 Bit.
Ausgeben ID von K und O mit HKDF basierend auf SHA-256.
Eine Zeichenfolge zusätzlicher authentifizierter Daten bilden aad — das ist einfach eine Zeichenfolge wie: id=ID
Wenn der Benutzer ein Passwort festgelegt hat:
- ausgeben Pk aus dem Passwort und O mithilfe von PBKDF2, SHA-256, 800.000 Iterationen;
- das gleiche Salt wird für alles verwendet;
- Daten mit AES-GCM verschlüsseln, unter Verwendung des Schlüssels Pk, IV/Nonce N und übergeben aad.
Ein zwei Byte großes Tag zu den bereits verschlüsselten Daten hinzufügen, wenn ein Passwort verwendet wurde, oder zu den ursprünglichen Daten, wenn kein Passwort vorhanden war.
Das erste Byte ist entscheidend: es zeigt an, ob die Daten mit einem Passwort verschlüsselt sind:
- 0x73 — die Daten sind mit einem Passwort verschlüsselt;
- 0x13 — die Daten sind nicht mit einem Passwort verschlüsselt.
Das zweite Byte ist ein fester Wert von 0x37.
Das Ergebnis erneut mit AES-GCM verschlüsseln, unter Verwendung des gleichen iv = N und dem gleichen aad. Dies ergibt den endgültigen Chiffretext ct.
Bytes zu einer Zeichenfolge zusammenfügen: blob = N .. S .. ct
Senden blob zum Server zusammen mit ID. Der Server gibt zurück blob auf diesem ID und kann es nicht manipulieren: der Client überprüft zuerst ID geschrieben und verwendet N und K noch vor der Entschlüsselung und dann — über aad.
Der Client speichert K. K wird niemals an den Server gesendet. Pk wird auch nicht gesendet; alles, was mit dem Passwort zu tun hat, wird aus dem Speicher gelöscht.
Der Client erstellt einen Link: origin/#ID/K
Hier ID und K — Zeichenfolgen im base64url-Format.
Wenn der Empfänger den Link öffnet:
- der Browser ignoriert alles, was mit # beginnt; dies wird location.hash genannt;
- die Client-Anwendung wird vom Server geladen;
- meiner Meinung nach ist das das größte Risiko: wir stoßen tatsächlich erneut darauf, dass 'TLS löchrig' ist;
- allerdings steht es nichts im Weg, den Client offline zu speichern;
- idealerweise sollte es einen separaten Standalone-Client geben.
Der Client-JavaScript überprüft location.hash, und wenn dort ID und Kist, lädt er die Daten vom Server.
Dann überprüft er sie, entschlüsselt sie und, falls nötig, fordert er ein Passwort an und entschlüsselt erneut.
Lizenz
Das Projekt wird unter GPLv3 verbreitet.
Quelle: linux.org.ru
