Die Veröffentlichung von Ad Nihilum 0.4.3 — einem minimalistischen Dienst zum Austausch von verschlüsselten Nachrichten nach dem Prinzip „gelesen — verbrannt“, der in erster Linie auf Self-Hosting ausgerichtet ist, fand statt.
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).
Merkmale
- lokale Verschlüsselung und Entschlüsselung, Server sieht den Schlüssel niemals;
- Unterstützung einer zusätzlichen Verschlüsselungsschicht mit einem Passwort, über das (1) der Server nichts erfahren kann, (2) das nicht über den übermittelten Link ermittelt werden kann;
- Das Projekt umfasst etwa 2200 Zeilen Serverseitigen Codes in C und 600 Zeilen Client-Code in JS, was die Prüfung erleichtert;
- Ad Nihilum ist lediglich von libmicrohttpd abhängig. Für die Erstellung von QR-Codes wird eine modifizierte Version von QRCode.js bereitgestellt;
- Eine Anleitung zum schnellen Einrichten eines lokalen Dienstes ohne externe IP ist enthalten;
- Ad Nihilum funktioniert auch auf Android, ein entsprechendes Skript zum Erstellen in Termux ist beigefügt;
- einzelner und synchroner Server.
Änderungen
Umfangreiches Redesign
- Die Seiten zum Senden und Empfangen von Nachrichten wurden getrennt, der entsprechende Client-Code.
- Das Design wurde insgesamt stark verändert und unter Berücksichtigung der Wünsche der User angepasst.
- Einfache und lokale Clients:
- Client-Seiten können lokal gespeichert und aus file:// verwendet werden.
Browser-Richtlinien
- CSP wurde zur Bekämpfung von XSS implementiert;
- der Server sendet HSTS.
Weitere Änderungen
- Das Projekt wurde von Epha-ots umbenannt;
- Die Domain adnihilum.net wurde gekauft;
- TLS wird durch Let’s Encrypt bereitgestellt, das sollte man im Hinterkopf behalten (kein Geld);
- Die Arbeit mit Dateien wurde vereinfacht;
- Übergang zu Fat-Pointern;
- kleine Bugs wurden behoben;
- auto-jsminify und Kompilierung der Client-Dateien während des Builds über CMake.
Protokollübersicht
Drei zufällige Werte generieren: Schlüssel K, Initialisierungsvektor N und Salz S. K — 256 Bit, N — 96 Bit, S — 128 Bit.
Ausgabe ID aus K und S unter Verwendung von HKDF auf Basis von SHA-256.
Eine Zeichenfolge zusätzlicher authentifizierter Daten bilden aad — das ist einfach eine Zeichenfolge: id=ID
Wenn der Benutzer ein Passwort eingegeben hat:
- ausgeben Pk aus dem Passwort und S mithilfe von PBKDF2, SHA-256, 800000 Iterationen;
- das gleiche Salz wird für alles verwendet;
- Daten mit AES-GCM verschlüsseln, unter Verwendung des Schlüssels Pk, IV/Nonce N und übergeben aad.
Einen zweibyteslangen Tag zu bereits verschlüsselten Daten hinzufügen, wenn ein Passwort vorhanden war, oder zu den Ausgangsdaten, wenn kein Passwort vorhanden war.
Das erste Byte hat eine Bedeutung: Es zeigt an, ob die Daten mit einem Passwort verschlüsselt wurden:
- 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 0x37.
Das Ergebnis erneut mit AES-GCM verschlüsseln, unter Verwendung des selben iv = N und des selben aad. Das ergibt den finalen Chiffretext ct.
Die Bytes zu einer Zeichenkette zusammenfügen: blob = N .. S .. ct
Senden blob an den Server zusammen mit ID. Der Server gibt zurück blob diesem ID und kann es nicht ersetzen: Der Client wird zuerst überprüfen ID unter Verwendung von 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 dies die größte Schwachstelle: wir stoßen tatsächlich wieder auf das Problem, dass «TLS löchrig» ist;
- nichts hindert jedoch daran, 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 K, lädt er die Daten vom Server.
Dann überprüft er sie, entschlüsselt sie und, falls nötig, fordert das Passwort an und entschlüsselt sie erneut.
Lizenz
Das Projekt wird unter GPLv3 verbreitet.
Quelle: linux.org.ru
