Hinweis
Die Vorschlagsphase ist beendet. Siehe SPEC für die offizielle Spezifikation. Dieser Vorschlag kann weiterhin als Hintergrundinformation herangezogen werden.
Übersicht
Dieser Vorschlag beschreibt ein authentifiziertes Schlüsselvereinbarungsprotokoll zur Verbesserung der Widerstandsfähigkeit von NTCP gegen verschiedene Formen automatisierter Identifikation und Angriffe.
Der Vorschlag ist wie folgt gegliedert: die Sicherheitsziele werden präsentiert, gefolgt von einer Diskussion des grundlegenden Protokolls. Anschließend wird eine vollständige Spezifikation aller Protokollnachrichten gegeben. Abschließend werden router-Adressen und Versionsidentifikation diskutiert. Ein Anhang, der einen generischen Angriff auf gängige Padding-Verfahren behandelt, ist ebenfalls enthalten, sowie ein Anhang mit einer Reihe von Kandidaten für die authentifizierte Verschlüsselung.
Wie bei anderen I2P-Transporten ist NTCP2 ausschließlich für den Punkt-zu-Punkt-Transport (router-zu-router) von I2NP-Nachrichten definiert. Es ist keine allgemeine Datenleitung.
Motivation
NTCP Daten werden nach der ersten Nachricht verschlüsselt (und die erste Nachricht erscheint als zufällige Daten), wodurch eine Protokollidentifikation durch “Payload-Analyse” verhindert wird. Es ist jedoch weiterhin anfällig für Protokollidentifikation durch “Flow-Analyse”. Das liegt daran, dass die ersten 4 Nachrichten (d.h. der Handshake) eine feste Länge haben (288, 304, 448 und 48 Bytes).
Durch das Hinzufügen zufälliger Mengen an zufälligen Daten zu jeder der Nachrichten können wir es erheblich schwieriger machen.
Die Autoren erkennen an, dass standardmäßige Sicherheitspraktiken die Verwendung eines bestehenden Protokolls wie TLS nahelegen würden, aber dies ist Prop104 und es hat seine eigenen Probleme. Wo angemessen, wurden “zukünftige Arbeit”-Absätze hinzugefügt, um fehlende Funktionen oder Diskussionsthemen zu kennzeichnen.
Designziele
Unterstützung von NTCP 1 und 2 auf einem einzelnen Port, automatische Erkennung und Veröffentlichung als ein einziger “Transport” (d.h. RouterAddress) in der NetDB.
Unterstützung für nur Version 1, nur Version 2, oder 1+2 in der NetDB in einem separaten Feld veröffentlichen und standardmäßig nur Version 1 verwenden (Versionsunterstützung nicht an eine bestimmte Router-Version binden)
Sicherstellen, dass alle Implementierungen (Java/i2pd/Kovri/go) Version 2 Unterstützung nach ihren eigenen Zeitplänen hinzufügen können (oder auch nicht)
Füge zufällige Auffüllung zu allen NTCP-Nachrichten hinzu, einschließlich Handshake- und Datennachrichten (d.h. Längenverschleierung, sodass nicht alle Nachrichten ein Vielfaches von 16 Bytes sind) Stelle einen Optionsmechanismus bereit, damit beide Seiten minimale und maximale Auffüllung und/oder Auffüllungsverteilung anfordern können. Die spezifischen Details der Auffüllungsverteilung sind implementierungsabhängig und können im Protokoll selbst spezifiziert werden oder auch nicht.
Verschleiert den Inhalt von Nachrichten, die nicht verschlüsselt sind (1 und 2), ausreichend, damit DPI-Boxen und AV-Signaturen sie nicht einfach klassifizieren können. Stellt außerdem sicher, dass Nachrichten, die an einen einzelnen Peer oder eine Gruppe von Peers gesendet werden, kein ähnliches Bitmuster aufweisen.
Behebung des Bitverlusts in DH aufgrund des Java-Formats Ticket1112, möglicherweise (wahrscheinlich?) durch Umstellung auf X25519.
Auf eine echte Schlüsselableitungsfunktion (KDF) umsteigen, anstatt das DH-Ergebnis direkt zu verwenden?
“Probing resistance” hinzufügen (wie Tor es nennt); dies umfasst Replay-Resistenz.
2-Wege-authentifizierten Schlüsselaustausch (2W-AKE) beibehalten. 1W-AKE ist für unsere Anwendung nicht ausreichend.
Verwenden Sie weiterhin die Signaturen mit variabler Art und Länge (vom veröffentlichten RouterIdentity-Signaturschlüssel) als Teil der Authentifizierung. Verlassen Sie sich auf einen statischen öffentlichen Schlüssel, der in der RouterInfo veröffentlicht ist, als weiteren Teil der Authentifizierung.
Optionen/Version im Handshake für zukünftige Erweiterbarkeit hinzufügen.
Fügen Sie nach Möglichkeit Widerstand gegen böswillige MitM-TCP-Segmentierung hinzu.
Fügen Sie nicht signifikant zur CPU-Last hinzu, die für den Verbindungsaufbau erforderlich ist; reduzieren Sie diese wenn möglich erheblich.
Message-Authentifizierung (MAC) hinzufügen, möglicherweise HMAC-SHA256 und Poly1305, und Adler-Prüfsumme entfernen.
I2NP-Header verkürzen und vereinfachen: Ablaufzeit auf 4 Bytes verkürzen, wie bei SSU. Ein-Byte-verkürzte SHA256-Prüfsumme entfernen.
Falls möglich, die 4-Nachrichten-, Zwei-Round-Trip-Handshake auf eine 3-Nachrichten-, Ein-Round-Trip-Handshake reduzieren, wie in SSU. Dies würde erfordern, Bobs Signatur von Nachricht 4 zu Nachricht 2 zu verschieben. Recherchiere den Grund für 4 Nachrichten in den zehn Jahre alten E-Mail-/Status-/Meeting-Archiven.
Minimiere den Protokoll-Overhead vor dem Padding. Obwohl Padding hinzugefügt wird, und möglicherweise viel davon, ist Overhead vor dem Padding trotzdem Overhead. Knoten mit geringer Bandbreite müssen NTCP2 verwenden können.
Zeitstempel für Replay- und Abweichungserkennung verwalten.
Vermeiden Sie alle Jahr-2038-Probleme in Zeitstempeln, muss mindestens bis 2106 funktionieren.
Erhöhe die maximale Nachrichtengröße von 16K auf 32K oder 64K.
Alle neuen kryptographischen Primitive sollten in Bibliotheken für die Verwendung in Java (1.7), C++ und Go router-Implementierungen verfügbar sein.
Entwickler-Vertreter der Java-, C++- und Go-Router in das Design einbeziehen.
Änderungen minimieren (aber es wird trotzdem viele geben).
Unterstütze beide Versionen in einem gemeinsamen Code-Set (dies ist möglicherweise nicht machbar und ist in jedem Fall implementierungsabhängig).
Non-Goals
Kugelsichere DPI-Resistenz… das wären pluggable transports, Prop109.
Ein TLS-basierter (oder HTTPS-ähnlicher) Transport… das wäre Prop104.
Es ist in Ordnung, die symmetrische Stream-Kryptographie zu ändern.
Timing-basierte DPI-Resistenz (Timing/Verzögerungen zwischen Nachrichten können implementierungsabhängig sein; Verzögerungen innerhalb von Nachrichten können an jedem Punkt eingeführt werden, einschließlich vor dem Senden des zufälligen Paddings, zum Beispiel). Künstliche Verzögerungen (was obfs4 IAT oder Inter-Arrival-Time nennt) sind unabhängig vom Protokoll selbst.
Abstreitbarkeit der Teilnahme an einer Sitzung (es sind Signaturen enthalten).
Nicht-Ziele, die teilweise überdacht oder diskutiert werden können:
Der Grad des Schutzes gegen Deep Packet Inspection (DPI)
Post-Quantum (PQ) Sicherheit
Abstreitbarkeit
Related Goals
- Implementierung einer NTCP 1/2 Testumgebung
Security Goals
Wir betrachten drei Parteien:
- Alice, die eine neue Sitzung etablieren möchte.
- Bob, mit dem Alice eine Sitzung etablieren möchte.
- Mallory, der “Man in the Middle” zwischen Alice und Bob.
Höchstens zwei Teilnehmer können aktive Angriffe durchführen.
Alice und Bob besitzen beide ein statisches Schlüsselpaar, das in ihrer RouterIdentity enthalten ist.
Das vorgeschlagene Protokoll versucht es Alice und Bob zu ermöglichen, sich auf einen gemeinsamen geheimen Schlüssel (K) unter den folgenden Anforderungen zu einigen:
Sicherheit des privaten Schlüssels: weder Bob noch Mallory erfahren etwas über Alices statischen privaten Schlüssel. Symmetrisch dazu erfährt Alice nichts über Bobs statischen privaten Schlüssel.
Der Session-Key K ist nur Alice und Bob bekannt.
Perfect Forward Secrecy: der vereinbarte Sitzungsschlüssel bleibt auch in Zukunft geheim, selbst wenn die statischen privaten Schlüssel von Alice und/oder Bob offengelegt werden, nachdem der Schlüssel vereinbart wurde.
Zweiseitige Authentifizierung: Alice ist sicher, dass sie eine Sitzung mit Bob aufgebaut hat, und umgekehrt.
Schutz gegen Online-DPI: Sicherstellen, dass es nicht trivial ist zu erkennen, dass Alice und Bob das Protokoll verwenden, wenn nur einfache Deep Packet Inspection (DPI)-Techniken eingesetzt werden. Siehe unten.
Begrenzte Abstreitbarkeit: weder Alice noch Bob können ihre Teilnahme am Protokoll abstreiten, aber wenn einer der beiden den gemeinsamen Schlüssel preisgibt, kann die andere Partei die Authentizität des Inhalts der übertragenen Daten abstreiten.
Der vorliegende Vorschlag versucht, alle fünf Anforderungen basierend auf dem Station-To-Station (STS) Protokoll zu erfüllen. Beachten Sie, dass dieses Protokoll auch die Grundlage für das SSU Protokoll ist.
Additional DPI Discussion
Wir nehmen zwei DPI-Komponenten an:
1) Online DPI
Online-DPI, die alle Datenströme in Echtzeit inspiziert. Verbindungen können blockiert oder anderweitig manipuliert werden. Verbindungsdaten oder Metadaten können identifiziert und für die Offline-Analyse gespeichert werden. Die Online-DPI hat keinen Zugang zur I2P-Netzwerkdatenbank. Die Online-DPI verfügt nur über begrenzte Echtzeit-Rechenkapazitäten, einschließlich Längenberechnung, Feldinspektion und einfache Berechnungen wie XOR. Die Online-DPI verfügt über die Fähigkeit schneller Echtzeit-Kryptographie-Funktionen wie AES, AEAD und Hashing, aber diese wären zu aufwändig, um sie auf die meisten oder alle Datenströme anzuwenden. Jede Anwendung dieser kryptographischen Operationen würde nur auf Datenströme bei IP/Port-Kombinationen angewendet, die zuvor durch Offline-Analyse identifiziert wurden. Die Online-DPI verfügt nicht über die Fähigkeit für rechenintensive kryptographische Funktionen wie DH oder elligator2. Die Online-DPI ist nicht speziell zur Erkennung von I2P entwickelt, obwohl sie begrenzte Klassifizierungsregeln für diesen Zweck haben könnte.
Es ist ein Ziel, die Protokollidentifizierung durch eine Online-DPI zu verhindern.
Der Begriff der Online- oder „direkten" DPI wird hier so verstanden, dass er die folgenden Angreifer-Fähigkeiten umfasst:
Die Fähigkeit, alle vom Ziel gesendeten oder empfangenen Daten zu inspizieren.
Die Fähigkeit, Operationen auf den beobachteten Daten durchzuführen, wie das Anwenden von Blockchiffren oder Hash-Funktionen.
Die Fähigkeit, zuvor gesendete Nachrichten zu speichern und mit ihnen zu vergleichen.
Die Fähigkeit, Pakete zu modifizieren, zu verzögern oder zu fragmentieren.
Jedoch wird angenommen, dass die Online-DPI die folgenden Einschränkungen hat:
Die Unfähigkeit, IP-Adressen auf router hashes abzubilden. Während dies mit Echtzeitbzugang zur netDb trivial ist, würde es ein DPI-System erfordern, das speziell darauf ausgelegt ist, I2P zu erfassen.
Die Unfähigkeit, Timing-Informationen zur Protokollerkennung zu verwenden.
Grundsätzlich enthält die Online-DPI-Toolbox keine eingebauten Werkzeuge, die speziell für die I2P-Erkennung entwickelt wurden. Dazu gehört auch die Erstellung von “Honeypots”, die beispielsweise nicht-zufällige Füllzeichen in ihren Nachrichten enthalten würden. Beachten Sie, dass dies maschinelle Lernsysteme oder hochkonfigurierbare DPI-Tools nicht ausschließt, solange sie die anderen Anforderungen erfüllen.
Um die Payload-Analyse zu verhindern, wird sichergestellt, dass alle Nachrichten von zufälligen Daten nicht zu unterscheiden sind. Dies erfordert auch, dass ihre Länge zufällig ist, was komplizierter ist als nur zufällige Füllbytes hinzuzufügen. Tatsächlich argumentieren die Autoren in Anhang A, dass ein naives (d.h. gleichmäßiges) Padding-Schema das Problem nicht löst. Anhang A schlägt daher vor, entweder zufällige Verzögerungen einzubauen oder ein alternatives Padding-Schema zu entwickeln, das angemessenen Schutz gegen den vorgeschlagenen Angriff bieten kann.
Um sich gegen den sechsten Punkt oben zu schützen, sollten Implementierungen zufällige Verzögerungen im Protokoll einbauen. Solche Techniken werden von diesem Vorschlag nicht abgedeckt, aber sie könnten auch die Probleme mit der Padding-Länge lösen. Zusammenfassend bietet der Vorschlag einen guten Schutz gegen Payload-Analyse (wenn die Überlegungen in Anhang A berücksichtigt werden), aber nur begrenzten Schutz gegen Flow-Analyse.
2) Offline DPI
Offline DPI, die von der Online-DPI gespeicherte Daten für spätere Analysen untersucht. Die Offline-DPI kann speziell zur Erkennung von I2P entwickelt worden sein. Die Offline-DPI hat keinen Echtzeitzugang zur I2P-Netzwerkdatenbank. Die Offline-DPI hat Zugang zu dieser und anderen I2P-Spezifikationen. Die Offline-DPI verfügt über unbegrenzte Rechenkapazität, einschließlich aller in dieser Spezifikation definierten kryptographischen Funktionen.
Die Offline-DPI hat nicht die Fähigkeit, bestehende Verbindungen zu blockieren. Die Offline-DPI hat jedoch die Möglichkeit, nahezu in Echtzeit (innerhalb von Minuten nach der Einrichtung) an Host/Port von Parteien zu senden, beispielsweise TCP RST. Die Offline-DPI hat die Möglichkeit, nahezu in Echtzeit (innerhalb von Minuten nach der Einrichtung) vorherige Nachrichten (modifiziert oder nicht) für “Probing” oder andere Zwecke zu wiederholen.
Es ist nicht das Ziel, die Protokollidentifikation durch eine Offline-DPI zu verhindern. Jede Dekodierung von verschleierten Daten in den ersten beiden Nachrichten, die von I2P-Routern implementiert wird, kann auch von der Offline-DPI implementiert werden.
Es ist ein Ziel, Verbindungsversuche abzulehnen, die eine Wiederholung vorheriger Nachrichten verwenden.
Future work
Berücksichtigen Sie das Verhalten des Protokolls, wenn Pakete von einem Angreifer verworfen oder neu geordnet werden. Aktuelle interessante Arbeiten in diesem Bereich finden Sie in IACR-1150.
Eine genauere Klassifizierung von DPI-Systemen bereitstellen, unter Berücksichtigung der bestehenden Literatur zu diesem Thema.
Diskutieren Sie die formale Sicherheit des vorgeschlagenen Protokolls, idealerweise unter Berücksichtigung des DPI-Angreifermodells.
Noise Protocol Framework
Dieser Vorschlag stellt die Anforderungen basierend auf dem Noise Protocol Framework NOISE (Revision 33, 2017-10-04) bereit. Noise hat ähnliche Eigenschaften wie das Station-To-Station-Protokoll, welches die Grundlage für das SSU-Protokoll bildet. In der Noise-Terminologie ist Alice der Initiator und Bob der Responder.
NTCP2 basiert auf dem Noise-Protokoll Noise_XK_25519_ChaChaPoly_SHA256. (Der tatsächliche Bezeichner für die anfängliche Schlüsselableitungsfunktion ist “Noise_XKaesobfse+hs2+hs3_25519_ChaChaPoly_SHA256” um I2P-Erweiterungen anzuzeigen - siehe KDF 1 Abschnitt unten) Dieses Noise-Protokoll verwendet die folgenden Primitive:
Handshake Pattern: XK Alice überträgt ihren Schlüssel an Bob (X) Alice kennt Bobs statischen Schlüssel bereits (K)
DH Function: X25519 X25519 DH mit einer Schlüssellänge von 32 Bytes wie in RFC-7748 spezifiziert.
Cipher Function: ChaChaPoly AEAD_CHACHA20_POLY1305 wie in RFC-7539 Abschnitt 2.8 spezifiziert. 12 Byte Nonce, wobei die ersten 4 Bytes auf null gesetzt sind.
Hash Function: SHA256 Standard 32-Byte-Hash, bereits umfassend in I2P verwendet.
Sicherheitsziele
Dieser Vorschlag definiert die folgenden Verbesserungen für Noise_XK_25519_ChaChaPoly_SHA256. Diese folgen im Allgemeinen den Richtlinien in NOISE Abschnitt 13.
Klartext-Ephemeralschlüssel werden mit AES-Verschlüsselung unter Verwendung eines bekannten Schlüssels und IV verschleiert. Dies ist schneller als elligator2.
Zufällige Klartext-Auffüllung wird zu Nachrichten 1 und 2 hinzugefügt. Die Klartext-Auffüllung ist in der Handshake-Hash (MixHash) Berechnung enthalten. Siehe die KDF-Abschnitte unten für Nachricht 2 und Nachricht 3 Teil 1. Zufällige AEAD-Auffüllung wird zu Nachricht 3 und Datenphase-Nachrichten hinzugefügt.
Ein zwei-Byte-Frame-Längenfeld wird hinzugefügt, wie es für Noise über TCP erforderlich ist und wie in obfs4. Dies wird nur in den Datenphase-Nachrichten verwendet. Nachricht 1 und 2 AEAD-Frames haben eine feste Länge. Nachricht 3 Teil 1 AEAD-Frame hat eine feste Länge. Die Länge des Nachricht 3 Teil 2 AEAD-Frames wird in Nachricht 1 spezifiziert.
Das zwei-Byte-Framelängenfeld wird mit SipHash-2-4 verschleiert, wie in obfs4.
Das Payload-Format ist für die Nachrichten 1, 2, 3 und die Datenphase definiert. Natürlich ist dies nicht in Noise definiert.
New Cryptographic Primitives for I2P
Bestehende I2P router-Implementierungen werden Implementierungen für die folgenden standardmäßigen kryptographischen Primitive benötigen, die für aktuelle I2P-Protokolle nicht erforderlich sind:
X25519 Schlüsselerzeugung und DH
AEAD_ChaCha20_Poly1305 (im Folgenden als ChaChaPoly abgekürzt)
SipHash-2-4
Processing overhead estimate
Nachrichtengrößen für die 3 Nachrichten:
- 64 Bytes + Padding (NTCP war 288 Bytes) 2) 64 Bytes + Padding (NTCP war 304 Bytes) 3) ca. 64 Bytes + Alice Router-Info + Padding Durchschnittliche Router-Info ist etwa 750 Bytes Gesamtdurchschnitt 814 Bytes vor Padding (NTCP war 448 Bytes) 4) nicht erforderlich in NTCP2 (NTCP war 48 Bytes)
Gesamt vor Padding: NTCP2: 942 Bytes NTCP: 1088 Bytes Beachten Sie, dass wenn Alice sich mit Bob verbindet, um eine DatabaseStore-Nachricht ihrer RouterInfo zu senden, diese Nachricht nicht erforderlich ist, wodurch ungefähr 800 Bytes eingespart werden.
Die folgenden kryptografischen Operationen sind von jeder Partei erforderlich, um den Handshake abzuschließen und die Datenphase zu starten:
- AES: 2
- SHA256: 7 (Alice), 6 (Bob) (nicht einschließlich 1 Alice, 2 Bob vorberechnet für alle Verbindungen) (nicht einschließlich HMAC-SHA256)
- HMAC-SHA256: 19
- ChaChaPoly: 4
- X25519 Schlüsselerzeugung: 1
- X25519 DH: 3
- Signaturverifizierung: 1 (Bob) (Alice hat zuvor signiert beim Erstellen ihrer RI) Vermutlich Ed25519 (abhängig vom RI-Signaturtyp)
Die folgenden kryptographischen Operationen sind von jeder Partei für jede Datenphasennachricht erforderlich:
- SipHash: 1
- ChaChaPoly: 1
Messages
Alle NTCP2-Nachrichten sind höchstens 65537 Bytes lang. Das Nachrichtenformat basiert auf Noise-Nachrichten, mit Änderungen für Framing und Ununterscheidbarkeit. Implementierungen, die Standard-Noise-Bibliotheken verwenden, müssen empfangene Nachrichten möglicherweise zum/vom Noise-Nachrichtenformat vorverarbeiten. Alle verschlüsselten Felder sind AEAD-Chiffretexte.
Die Aufbau-Sequenz ist wie folgt:
Alice Bob
SessionRequest ------------------->
<------------------- SessionCreated
SessionConfirmed ----------------->
Mit Noise-Terminologie ist die Aufbau- und Datensequenz wie folgt: (Payload Security Properties)
XK(s, rs): Authentication Confidentiality
<- s
...
-> e, es 0 2
<- e, ee 2 1
-> s, se 2 5
<- 2 5
Sobald eine Sitzung hergestellt wurde, können Alice und Bob Data-Nachrichten austauschen.
Alle Nachrichtentypen (SessionRequest, SessionCreated, SessionConfirmed, Data und TimeSync) sind in diesem Abschnitt spezifiziert.
Einige Notationen:
- RH_A = Router Hash für Alice (32 Bytes)
- RH_B = Router Hash für Bob (32 Bytes)
Authenticated Encryption
Es gibt drei separate authentifizierte Verschlüsselungsinstanzen (CipherStates). Eine während der Handshake-Phase und zwei (Senden und Empfangen) für die Datenphase. Jede hat ihren eigenen Schlüssel von einer KDF.
Verschlüsselte/authentifizierte Daten werden dargestellt als
+----+----+----+----+----+----+----+----+
| |
+ +
| Encrypted and authenticated data |
~ . . . ~
| |
+----+----+----+----+----+----+----+----+
Nicht-Ziele
Verschlüsseltes und authentifiziertes Datenformat.
Eingaben für die Verschlüsselungs-/Entschlüsselungsfunktionen:
k :: 32 byte cipher key, as generated from KDF
nonce :: Counter-based nonce, 12 bytes.
Starts at 0 and incremented for each message.
First four bytes are always zero.
Last eight bytes are the counter, little-endian encoded.
Maximum value is 2**64 - 2.
Connection must be dropped and restarted after
it reaches that value.
The value 2**64 - 1 must never be sent.
ad :: In handshake phase:
Associated data, 32 bytes.
The SHA256 hash of all preceding data.
In data phase:
Zero bytes
data :: Plaintext data, 0 or more bytes
Ausgabe der Verschlüsselungsfunktion, Eingabe der Entschlüsselungsfunktion:
+----+----+----+----+----+----+----+----+
|Obfs Len | |
+----+----+ +
| ChaCha20 encrypted data |
~ . . . ~
| |
+----+----+----+----+----+----+----+----+
| Poly1305 Message Authentication Code |
+ (MAC) +
| 16 bytes |
+----+----+----+----+----+----+----+----+
Obfs Len :: Length of (encrypted data + MAC) to follow, 16 - 65535
Obfuscation using SipHash (see below)
Not used in message 1 or 2, or message 3 part 1, where the length is fixed
Not used in message 3 part 1, as the length is specified in message 1
encrypted data :: Same size as plaintext data, 0 - 65519 bytes
MAC :: Poly1305 message authentication code, 16 bytes
Für ChaCha20 entspricht das hier Beschriebene RFC-7539, das auch ähnlich in TLS RFC-7905 verwendet wird.
Notes
Da ChaCha20 eine Stream-Cipher ist, müssen Klartexte nicht gepaddet werden. Zusätzliche Keystream-Bytes werden verworfen.
Der Schlüssel für die Verschlüsselung (256 Bits) wird mittels der SHA256 KDF vereinbart. Die Details der KDF für jede Nachricht sind in separaten Abschnitten unten aufgeführt.
ChaChaPoly-Frames für Nachrichten 1, 2 und den ersten Teil von Nachricht 3 haben eine bekannte Größe. Beginnend mit dem zweiten Teil von Nachricht 3 haben Frames eine variable Größe. Die Größe von Nachricht 3 Teil 1 wird in Nachricht 1 angegeben. Beginnend mit der Datenphase werden Frames mit einer zwei-Byte-Länge vorangestellt, die mit SipHash wie in obfs4 verschleiert wird.
Padding befindet sich außerhalb des authentifizierten Datenrahmens für Nachrichten 1 und 2. Das Padding wird in der KDF für die nächste Nachricht verwendet, sodass Manipulationen erkannt werden. Ab Nachricht 3 befindet sich Padding innerhalb des authentifizierten Datenrahmens.
Verwandte Ziele
In Nachrichten 1, 2 und Nachricht 3 Teile 1 und 2 ist die AEAD-Nachrichtengröße im Voraus bekannt. Bei einem AEAD-Authentifizierungsfehler muss der Empfänger die weitere Nachrichtenverarbeitung stoppen und die Verbindung schließen, ohne zu antworten. Dies sollte ein abnormales Schließen sein (TCP RST).
Für Widerstand gegen Probing sollte Bob in Nachricht 1 nach einem AEAD-Fehler ein zufälliges Timeout (Bereich noch zu bestimmen) setzen und dann eine zufällige Anzahl von Bytes (Bereich noch zu bestimmen) lesen, bevor er den Socket schließt. Bob sollte eine Blacklist von IPs mit wiederholten Fehlern führen.
In der Datenphase wird die AEAD-Nachrichtengröße mit SipHash “verschlüsselt” (verschleiert). Es muss darauf geachtet werden, kein Entschlüsselungsorakel zu erstellen. Bei einem AEAD-Authentifizierungsfehler in der Datenphase sollte der Empfänger eine zufällige Zeitüberschreitung (Bereich noch festzulegen) setzen und dann eine zufällige Anzahl von Bytes (Bereich noch festzulegen) lesen. Nach dem Lesen oder bei Lese-Zeitüberschreitung sollte der Empfänger eine Nutzlast mit einem Terminierungsblock senden, der einen “AEAD-Fehler”-Grund-Code enthält, und die Verbindung schließen.
Führe die gleiche Fehlerbehandlung für einen ungültigen Längenfeldwert in der Datenphase aus.
Key Derivation Function (KDF) (for handshake message 1)
Die KDF generiert einen handshake phase cipher key k aus dem DH-Ergebnis, unter Verwendung von HMAC-SHA256(key, data) wie in RFC-2104 definiert. Dies sind die Funktionen InitializeSymmetric(), MixHash() und MixKey(), genau wie in der Noise-Spezifikation definiert.
This is the "e" message pattern:
// Define protocol_name.
Set protocol_name = "Noise_XKaesobfse+hs2+hs3_25519_ChaChaPoly_SHA256"
(48 bytes, US-ASCII encoded, no NULL termination).
// Define Hash h = 32 bytes
h = SHA256(protocol_name);
Define ck = 32 byte chaining key. Copy the h data to ck.
Set ck = h
Define rs = Bob's 32-byte static key as published in the RouterInfo
// MixHash(null prologue)
h = SHA256(h);
// up until here, can all be precalculated by Alice for all outgoing connections
// Alice must validate that Bob's static key is a valid point on the curve here.
// Bob static key
// MixHash(rs)
// || below means append
h = SHA256(h || rs);
// up until here, can all be precalculated by Bob for all incoming connections
This is the "e" message pattern:
Alice generates her ephemeral DH key pair e.
// Alice ephemeral key X
// MixHash(e.pubkey)
// || below means append
h = SHA256(h || e.pubkey);
// h is used as the associated data for the AEAD in message 1
// Retain the Hash h for the message 2 KDF
End of "e" message pattern.
This is the "es" message pattern:
// DH(e, rs) == DH(s, re)
Define input_key_material = 32 byte DH result of Alice's ephemeral key and Bob's static key
Set input_key_material = X25519 DH result
// MixKey(DH())
Define temp_key = 32 bytes
Define HMAC-SHA256(key, data) as in [RFC-2104](https://tools.ietf.org/html/rfc2104)
// Generate a temp key from the chaining key and DH result
// ck is the chaining key, defined above
temp_key = HMAC-SHA256(ck, input_key_material)
// overwrite the DH result in memory, no longer needed
input_key_material = (all zeros)
// Output 1
// Set a new chaining key from the temp key
// byte() below means a single byte
ck = HMAC-SHA256(temp_key, byte(0x01)).
// Output 2
// Generate the cipher key k
Define k = 32 bytes
// || below means append
// byte() below means a single byte
k = HMAC-SHA256(temp_key, ck || byte(0x02)).
// overwrite the temp_key in memory, no longer needed
temp_key = (all zeros)
// retain the chaining key ck for message 2 KDF
End of "es" message pattern.
Zusätzliche DPI-Diskussion
Alice sendet an Bob.
Noise-Inhalt: Alices ephemerer Schlüssel X Noise-Payload: 16-Byte-Optionsblock Nicht-Noise-Payload: Zufällige Auffüllung
(Payload-Sicherheitseigenschaften)
XK(s, rs): Authentication Confidentiality
-> e, es 0 2
Authentication: None (0).
This payload may have been sent by any party, including an active attacker.
Confidentiality: 2.
Encryption to a known recipient, forward secrecy for sender compromise
only, vulnerable to replay. This payload is encrypted based only on DHs
involving the recipient's static key pair. If the recipient's static
private key is compromised, even at a later date, this payload can be
decrypted. This message can also be replayed, since there's no ephemeral
contribution from the recipient.
"e": Alice generates a new ephemeral key pair and stores it in the e
variable, writes the ephemeral public key as cleartext into the
message buffer, and hashes the public key along with the old h to
derive a new h.
"es": A DH is performed between the Alice's ephemeral key pair and the
Bob's static key pair. The result is hashed along with the old ck to
derive a new ck and k, and n is set to zero.
Der X-Wert wird verschlüsselt, um Payload-Ununterscheidbarkeit und Eindeutigkeit zu gewährleisten, die notwendige DPI-Gegenmaßnahmen sind. Wir verwenden AES-Verschlüsselung, um dies zu erreichen, anstatt komplexerer und langsamerer Alternativen wie elligator2. Asymmetrische Verschlüsselung mit Bobs router public key wäre viel zu langsam. Die AES-Verschlüsselung verwendet Bobs router hash als Schlüssel und Bobs IV, wie sie in der netDb veröffentlicht sind.
AES-Verschlüsselung dient nur dem Widerstand gegen DPI. Jede Partei, die Bobs Router-Hash und IV kennt, welche in der Netzwerkdatenbank veröffentlicht sind, kann den X-Wert in dieser Nachricht entschlüsseln.
Das Padding wird nicht von Alice verschlüsselt. Es kann erforderlich sein, dass Bob das Padding entschlüsselt, um Timing-Angriffe zu verhindern.
Rohe Inhalte:
+----+----+----+----+----+----+----+----+
| |
+ obfuscated with RH_B +
| AES-CBC-256 encrypted X |
+ (32 bytes) +
| |
+ +
| |
+----+----+----+----+----+----+----+----+
| |
+ +
| ChaChaPoly frame |
+ (32 bytes) +
| k defined in KDF for message 1 |
+ n = 0 +
| see KDF for associated data |
+----+----+----+----+----+----+----+----+
| unencrypted authenticated |
~ padding (optional) ~
| length defined in options block |
+----+----+----+----+----+----+----+----+
X :: 32 bytes, AES-256-CBC encrypted X25519 ephemeral key, little endian
key: RH_B
iv: As published in Bobs network database entry
padding :: Random data, 0 or more bytes.
Total message length must be 65535 bytes or less.
Total message length must be 287 bytes or less if
Bob is publishing his address as NTCP
(see Version Detection section below).
Alice and Bob will use the padding data in the KDF for message 2.
It is authenticated so that any tampering will cause the
next message to fail.
Unverschlüsselte Daten (Poly1305 Authentifizierungs-Tag nicht gezeigt):
+----+----+----+----+----+----+----+----+
| |
+ +
| X |
+ (32 bytes) +
| |
+ +
| |
+----+----+----+----+----+----+----+----+
| options |
+ (16 bytes) +
| |
+----+----+----+----+----+----+----+----+
| unencrypted authenticated |
+ padding (optional) +
| length defined in options block |
~ . . . ~
| |
+----+----+----+----+----+----+----+----+
X :: 32 bytes, X25519 ephemeral key, little endian
options :: options block, 16 bytes, see below
padding :: Random data, 0 or more bytes.
Total message length must be 65535 bytes or less.
Total message length must be 287 bytes or less if
Bob is publishing his address as "NTCP"
(see Version Detection section below)
Alice and Bob will use the padding data in the KDF for message 2.
It is authenticated so that any tampering will cause the
next message to fail.
Options-Block: Hinweis: Alle Felder sind big-endian.
+----+----+----+----+----+----+----+----+
| id | ver| padLen | m3p2len | Rsvd(0) |
+----+----+----+----+----+----+----+----+
| tsA | Reserved (0) |
+----+----+----+----+----+----+----+----+
id :: 1 byte, the network ID (currently 2, except for test networks)
As of 0.9.42. See proposal 147.
ver :: 1 byte, protocol version (currently 2)
padLen :: 2 bytes, length of the padding, 0 or more
Min/max guidelines TBD. Random size from 0 to 31 bytes minimum?
(Distribution to be determined, see Appendix A.)
m3p2Len :: 2 bytes, length of the the second AEAD frame in SessionConfirmed
(message 3 part 2) See notes below
Rsvd :: 2 bytes, set to 0 for compatibility with future options
tsA :: 4 bytes, Unix timestamp, unsigned seconds.
Wraps around in 2106
Reserved :: 4 bytes, set to 0 for compatibility with future options
Notes
Wenn die veröffentlichte Adresse “NTCP” ist, unterstützt Bob sowohl NTCP als auch NTCP2 auf demselben Port. Aus Kompatibilitätsgründen muss Alice beim Initiieren einer Verbindung zu einer als “NTCP” veröffentlichten Adresse die maximale Größe dieser Nachricht, einschließlich Padding, auf 287 Bytes oder weniger begrenzen. Dies ermöglicht die automatische Protokollerkennung durch Bob. Wenn als “NTCP2” veröffentlicht, gibt es keine Größenbeschränkung. Siehe die Abschnitte “Veröffentlichte Adressen” und “Versionserkennung” weiter unten.
Der einzigartige X-Wert im ersten AES-Block stellt sicher, dass der Chiffretext für jede Sitzung unterschiedlich ist.
Bob muss Verbindungen ablehnen, bei denen der Zeitstempel-Wert zu weit von der aktuellen Zeit abweicht. Nennen wir das maximale Delta “D”. Bob muss einen lokalen Cache von bereits verwendeten Handshake-Werten führen und Duplikate ablehnen, um Replay-Angriffe zu verhindern. Werte im Cache müssen eine Lebensdauer von mindestens 2*D haben. Die Cache-Werte sind implementierungsabhängig, jedoch kann der 32-Byte X-Wert (oder sein verschlüsseltes Äquivalent) verwendet werden.
Diffie-Hellman ephemeral keys dürfen niemals wiederverwendet werden, um kryptographische Angriffe zu verhindern, und eine Wiederverwendung wird als Replay-Angriff abgelehnt.
Die “KE”- und “auth”-Optionen müssen kompatibel sein, d.h. das geteilte Geheimnis K muss die entsprechende Größe haben. Wenn weitere “auth”-Optionen hinzugefügt werden, könnte dies implizit die Bedeutung des “KE”-Flags ändern, um eine andere KDF oder eine andere Verkürzungsgröße zu verwenden.
Bob muss hier validieren, dass Alices ephemerer Schlüssel ein gültiger Punkt auf der Kurve ist.
Padding sollte auf eine angemessene Menge begrenzt werden. Bob kann Verbindungen mit übermäßigem Padding ablehnen. Bob wird seine Padding-Optionen in Nachricht 2 angeben. Min/Max-Richtlinien noch festzulegen. Zufällige Größe von 0 bis 31 Bytes minimal? (Verteilung noch zu bestimmen, siehe Anhang A.)
Bei jedem Fehler, einschließlich AEAD, DH, Zeitstempel, scheinbarer Replay oder Schlüsselvalidierungsfehler, muss Bob die weitere Nachrichtenverarbeitung anhalten und die Verbindung ohne Antwort schließen. Dies sollte ein abnormaler Abschluss (TCP RST) sein. Für Probing-Resistenz sollte Bob nach einem AEAD-Fehler ein zufälliges Timeout (Bereich noch zu bestimmen) setzen und dann eine zufällige Anzahl von Bytes (Bereich noch zu bestimmen) lesen, bevor er den Socket schließt.
DoS-Abwehr: DH ist eine relativ teure Operation. Wie beim vorherigen NTCP-Protokoll sollten Router alle notwendigen Maßnahmen ergreifen, um CPU- oder Verbindungserschöpfung zu verhindern. Setzen Sie Limits für maximale aktive Verbindungen und maximale laufende Verbindungsaufbauten. Erzwingen Sie Read-Timeouts (sowohl pro Read als auch insgesamt für “Slowloris”). Begrenzen Sie wiederholte oder gleichzeitige Verbindungen von derselben Quelle. Führen Sie Blacklists für Quellen, die wiederholt fehlschlagen. Antworten Sie nicht auf AEAD-Fehler.
Um eine schnelle Versionserkennung und Handshake-Verfahren zu ermöglichen, müssen Implementierungen sicherstellen, dass Alice den gesamten Inhalt der ersten Nachricht puffert und dann auf einmal leert, einschließlich der Auffüllung. Dies erhöht die Wahrscheinlichkeit, dass die Daten in einem einzigen TCP-Paket enthalten sind (es sei denn, sie werden vom Betriebssystem oder Middleboxes segmentiert) und von Bob auf einmal empfangen werden. Zusätzlich müssen Implementierungen sicherstellen, dass Bob den gesamten Inhalt der zweiten Nachricht puffert und dann auf einmal leert, einschließlich der Auffüllung, und dass Bob den gesamten Inhalt der dritten Nachricht puffert und dann auf einmal leert. Dies dient ebenfalls der Effizienz und um die Wirksamkeit der zufälligen Auffüllung sicherzustellen.
“ver”-Feld: Das gesamte Noise-Protokoll, Erweiterungen und NTCP-Protokoll einschließlich Payload-Spezifikationen, was NTCP2 anzeigt. Dieses Feld kann verwendet werden, um die Unterstützung für zukünftige Änderungen anzuzeigen.
Message 3 Teil 2 Länge: Dies ist die Größe des zweiten AEAD-Frames (einschließlich 16-Byte MAC), der Alices Router Info und optionales Padding enthält, das in der SessionConfirmed-Nachricht gesendet wird. Da Router periodisch ihre Router Info regenerieren und neu veröffentlichen, kann sich die Größe der aktuellen Router Info ändern, bevor Nachricht 3 gesendet wird. Implementierungen müssen eine von zwei Strategien wählen: a) die aktuelle Router Info speichern, die in Nachricht 3 gesendet werden soll, damit die Größe bekannt ist, und optional Platz für Padding hinzufügen; b) die angegebene Größe ausreichend erhöhen, um eine mögliche Vergrößerung der Router Info zu ermöglichen, und beim tatsächlichen Senden von Nachricht 3 immer Padding hinzufügen. In beiden Fällen muss die in Nachricht 1 enthaltene “m3p2len”-Länge exakt der Größe dieses Frames entsprechen, wenn er in Nachricht 3 gesendet wird.
Bob muss die Verbindung beenden, wenn nach der Validierung von Nachricht 1 und dem Lesen des Paddings noch eingehende Daten vorhanden sind. Es sollten keine zusätzlichen Daten von Alice vorhanden sein, da Bob noch nicht mit Nachricht 2 geantwortet hat.
Das network ID Feld wird verwendet, um netzwerkübergreifende Verbindungen schnell zu identifizieren. Falls dieses Feld nicht null ist und nicht mit Bobs network ID übereinstimmt, sollte Bob die Verbindung trennen und zukünftige Verbindungen blockieren. Seit 0.9.42. Siehe proposal 147 für weitere Informationen.
Key Derivation Function (KDF) (for handshake message 2 and message 3 part 1)
// take h saved from message 1 KDF
// MixHash(ciphertext)
h = SHA256(h || 32 byte encrypted payload from message 1)
// MixHash(padding)
// Only if padding length is nonzero
h = SHA256(h || random padding from message 1)
This is the "e" message pattern:
Bob generates his ephemeral DH key pair e.
// h is from KDF for handshake message 1
// Bob ephemeral key Y
// MixHash(e.pubkey)
// || below means append
h = SHA256(h || e.pubkey);
// h is used as the associated data for the AEAD in message 2
// Retain the Hash h for the message 3 KDF
End of "e" message pattern.
This is the "ee" message pattern:
// DH(e, re)
Define input_key_material = 32 byte DH result of Alice's ephemeral key and Bob's ephemeral key
Set input_key_material = X25519 DH result
// overwrite Alice's ephemeral key in memory, no longer needed
// Alice:
e(public and private) = (all zeros)
// Bob:
re = (all zeros)
// MixKey(DH())
Define temp_key = 32 bytes
Define HMAC-SHA256(key, data) as in [RFC-2104](https://tools.ietf.org/html/rfc2104)
// Generate a temp key from the chaining key and DH result
// ck is the chaining key, from the KDF for handshake message 1
temp_key = HMAC-SHA256(ck, input_key_material)
// overwrite the DH result in memory, no longer needed
input_key_material = (all zeros)
// Output 1
// Set a new chaining key from the temp key
// byte() below means a single byte
ck = HMAC-SHA256(temp_key, byte(0x01)).
// Output 2
// Generate the cipher key k
Define k = 32 bytes
// || below means append
// byte() below means a single byte
k = HMAC-SHA256(temp_key, ck || byte(0x02)).
// overwrite the temp_key in memory, no longer needed
temp_key = (all zeros)
// retain the chaining key ck for message 3 KDF
End of "ee" message pattern.
2) SessionCreated
Bob sendet an Alice.
Noise-Inhalt: Bobs ephemerer Schlüssel Y Noise-Payload: 16-Byte-Optionsblock Nicht-Noise-Payload: Zufällige Auffüllung
(Payload-Sicherheitseigenschaften)
XK(s, rs): Authentication Confidentiality
<- e, ee 2 1
Authentication: 2.
Sender authentication resistant to key-compromise impersonation (KCI).
The sender authentication is based on an ephemeral-static DH ("es" or "se")
between the sender's static key pair and the recipient's ephemeral key pair.
Assuming the corresponding private keys are secure, this authentication cannot be forged.
Confidentiality: 1.
Encryption to an ephemeral recipient.
This payload has forward secrecy, since encryption involves an ephemeral-ephemeral DH ("ee").
However, the sender has not authenticated the recipient,
so this payload might be sent to any party, including an active attacker.
"e": Bob generates a new ephemeral key pair and stores it in the e variable,
writes the ephemeral public key as cleartext into the message buffer,
and hashes the public key along with the old h to derive a new h.
"ee": A DH is performed between the Bob's ephemeral key pair and the Alice's ephemeral key pair.
The result is hashed along with the old ck to derive a new ck and k, and n is set to zero.
Der Y-Wert wird verschlüsselt, um Payload-Ununterscheidbarkeit und Eindeutigkeit zu gewährleisten, die notwendige DPI-Gegenmaßnahmen sind. Wir verwenden AES-Verschlüsselung, um dies zu erreichen, anstatt komplexere und langsamere Alternativen wie elligator2. Asymmetrische Verschlüsselung mit Alices router-öffentlichem Schlüssel wäre viel zu langsam. Die AES-Verschlüsselung verwendet Bobs router-Hash als Schlüssel und den AES-Zustand aus Nachricht 1 (der mit Bobs IV initialisiert wurde, wie er in der netDb veröffentlicht ist).
AES-Verschlüsselung dient nur der DPI-Resistenz. Jede Partei, die Bobs router hash und IV kennt, welche in der network database veröffentlicht sind, und die ersten 32 Bytes von Nachricht 1 abgefangen hat, kann den Y-Wert in dieser Nachricht entschlüsseln.
Roher Inhalt:
+----+----+----+----+----+----+----+----+
| |
+ obfuscated with RH_B +
| AES-CBC-256 encrypted Y |
+ (32 bytes) +
| |
+ +
| |
+----+----+----+----+----+----+----+----+
| ChaChaPoly frame |
+ Encrypted and authenticated data +
| 32 bytes |
+ k defined in KDF for message 2 +
| n = 0; see KDF for associated data |
+ +
| |
+----+----+----+----+----+----+----+----+
| unencrypted authenticated |
+ padding (optional) +
| length defined in options block |
~ . . . ~
| |
+----+----+----+----+----+----+----+----+
Y :: 32 bytes, AES-256-CBC encrypted X25519 ephemeral key, little endian
key: RH_B
iv: Using AES state from message 1
Unverschlüsselte Daten (Poly1305 Auth-Tag nicht angezeigt):
+----+----+----+----+----+----+----+----+
| |
+ +
| Y |
+ (32 bytes) +
| |
+ +
| |
+----+----+----+----+----+----+----+----+
| options |
+ (16 bytes) +
| |
+----+----+----+----+----+----+----+----+
| unencrypted authenticated |
+ padding (optional) +
| length defined in options block |
~ . . . ~
| |
+----+----+----+----+----+----+----+----+
Y :: 32 bytes, X25519 ephemeral key, little endian
options :: options block, 16 bytes, see below
padding :: Random data, 0 or more bytes.
Total message length must be 65535 bytes or less.
Alice and Bob will use the padding data in the KDF for message 3 part 1.
It is authenticated so that any tampering will cause the
next message to fail.
Notes
Alice muss hier validieren, dass Bobs ephemerer Schlüssel ein gültiger Punkt auf der Kurve ist.
Padding sollte auf ein vernünftiges Maß begrenzt werden. Alice kann Verbindungen mit exzessivem Padding ablehnen. Alice wird ihre Padding-Optionen in Nachricht 3 spezifizieren. Min/Max-Richtlinien werden noch festgelegt. Zufällige Größe von 0 bis 31 Bytes mindestens? (Verteilung wird noch bestimmt, siehe Anhang A.)
Bei jedem Fehler, einschließlich AEAD, DH, Zeitstempel, offensichtlicher Wiederholung oder Schlüsselvalidierungsfehlern, muss Alice die weitere Nachrichtenverarbeitung stoppen und die Verbindung ohne Antwort schließen. Dies sollte ein abnormaler Abschluss (TCP RST) sein.
Um schnelle Handshakes zu ermöglichen, müssen Implementierungen sicherstellen, dass Bob den gesamten Inhalt der ersten Nachricht puffert und dann auf einmal sendet, einschließlich des Paddings. Dies erhöht die Wahrscheinlichkeit, dass die Daten in einem einzigen TCP-Paket enthalten sind (sofern sie nicht vom Betriebssystem oder Middleboxes segmentiert werden) und von Alice auf einmal empfangen werden. Dies dient auch der Effizienz und um die Wirksamkeit des zufälligen Paddings zu gewährleisten.
Alice muss die Verbindung beenden, falls nach der Validierung von Nachricht 2 und dem Einlesen des Paddings noch eingehende Daten vorhanden sind. Es sollten keine zusätzlichen Daten von Bob vorliegen, da Alice noch nicht mit Nachricht 3 geantwortet hat.
Options-Block: Hinweis: Alle Felder sind big-endian.
+----+----+----+----+----+----+----+----+
| Rsvd(0) | padLen | Reserved (0) |
+----+----+----+----+----+----+----+----+
| tsB | Reserved (0) |
+----+----+----+----+----+----+----+----+
Reserved :: 10 bytes total, set to 0 for compatibility with future options
padLen :: 2 bytes, big endian, length of the padding, 0 or more
Min/max guidelines TBD. Random size from 0 to 31 bytes minimum?
(Distribution to be determined, see Appendix A.)
tsB :: 4 bytes, big endian, Unix timestamp, unsigned seconds.
Wraps around in 2106
Notes
- Alice muss Verbindungen ablehnen, bei denen der Zeitstempel-Wert zu weit von der aktuellen Zeit abweicht. Nennen wir die maximale Delta-Zeit “D”. Alice muss einen lokalen Cache von zuvor verwendeten Handshake-Werten führen und Duplikate ablehnen, um Replay-Angriffe zu verhindern. Werte im Cache müssen eine Lebensdauer von mindestens 2*D haben. Die Cache-Werte sind implementierungsabhängig, jedoch kann der 32-Byte Y-Wert (oder sein verschlüsseltes Äquivalent) verwendet werden.
Issues
- Min/Max-Padding-Optionen hier einschließen?
Encryption for for handshake message 3 part 1, using message 2 KDF)
// take h saved from message 2 KDF
// MixHash(ciphertext)
h = SHA256(h || 24 byte encrypted payload from message 2)
// MixHash(padding)
// Only if padding length is nonzero
h = SHA256(h || random padding from message 2)
// h is used as the associated data for the AEAD in message 3 part 1, below
This is the "s" message pattern:
Define s = Alice's static public key, 32 bytes
// EncryptAndHash(s.publickey)
// EncryptWithAd(h, s.publickey)
// AEAD_ChaCha20_Poly1305(key, nonce, associatedData, data)
// k is from handshake message 1
// n is 1
ciphertext = AEAD_ChaCha20_Poly1305(k, n++, h, s.publickey)
// MixHash(ciphertext)
// || below means append
h = SHA256(h || ciphertext);
// h is used as the associated data for the AEAD in message 3 part 2
End of "s" message pattern.
Key Derivation Function (KDF) (for handshake message 3 part 2)
This is the "se" message pattern:
// DH(s, re) == DH(e, rs)
Define input_key_material = 32 byte DH result of Alice's static key and Bob's ephemeral key
Set input_key_material = X25519 DH result
// overwrite Bob's ephemeral key in memory, no longer needed
// Alice:
re = (all zeros)
// Bob:
e(public and private) = (all zeros)
// MixKey(DH())
Define temp_key = 32 bytes
Define HMAC-SHA256(key, data) as in [RFC-2104](https://tools.ietf.org/html/rfc2104)
// Generate a temp key from the chaining key and DH result
// ck is the chaining key, from the KDF for handshake message 1
temp_key = HMAC-SHA256(ck, input_key_material)
// overwrite the DH result in memory, no longer needed
input_key_material = (all zeros)
// Output 1
// Set a new chaining key from the temp key
// byte() below means a single byte
ck = HMAC-SHA256(temp_key, byte(0x01)).
// Output 2
// Generate the cipher key k
Define k = 32 bytes
// || below means append
// byte() below means a single byte
k = HMAC-SHA256(temp_key, ck || byte(0x02)).
// h from message 3 part 1 is used as the associated data for the AEAD in message 3 part 2
// EncryptAndHash(payload)
// EncryptWithAd(h, payload)
// AEAD_ChaCha20_Poly1305(key, nonce, associatedData, data)
// n is 0
ciphertext = AEAD_ChaCha20_Poly1305(k, n++, h, payload)
// MixHash(ciphertext)
// || below means append
h = SHA256(h || ciphertext);
// retain the chaining key ck for the data phase KDF
// retain the hash h for the data phase Additional Symmetric Key (SipHash) KDF
End of "se" message pattern.
// overwrite the temp_key in memory, no longer needed
temp_key = (all zeros)
3) SessionConfirmed
Alice sendet an Bob.
Noise-Inhalt: Alices statischer Schlüssel Noise-Payload: Alices RouterInfo und zufällige Auffüllung Nicht-Noise-Payload: keine
(Payload-Sicherheitseigenschaften)
XK(s, rs): Authentication Confidentiality
-> s, se 2 5
Authentication: 2.
Sender authentication resistant to key-compromise impersonation (KCI). The
sender authentication is based on an ephemeral-static DH ("es" or "se")
between the sender's static key pair and the recipient's ephemeral key
pair. Assuming the corresponding private keys are secure, this
authentication cannot be forged.
Confidentiality: 5.
Encryption to a known recipient, strong forward secrecy. This payload is
encrypted based on an ephemeral-ephemeral DH as well as an ephemeral-static
DH with the recipient's static key pair. Assuming the ephemeral private
keys are secure, and the recipient is not being actively impersonated by an
attacker that has stolen its static private key, this payload cannot be
decrypted.
"s": Alice writes her static public key from the s variable into the
message buffer, encrypting it, and hashes the output along with the old h
to derive a new h.
"se": A DH is performed between the Alice's static key pair and the Bob's
ephemeral key pair. The result is hashed along with the old ck to derive a
new ck and k, and n is set to zero.
Dies enthält zwei ChaChaPoly-Frames. Der erste ist Alices verschlüsselter statischer öffentlicher Schlüssel. Der zweite ist die Noise-Payload: Alices verschlüsselte RouterInfo, optionale Optionen und optionales Padding. Sie verwenden unterschiedliche Schlüssel, da die MixKey()-Funktion dazwischen aufgerufen wird.
Rohe Inhalte:
+----+----+----+----+----+----+----+----+
| |
+ ChaChaPoly frame (48 bytes) +
| Encrypted and authenticated |
+ Alice static key S +
| (32 bytes) |
+ +
| k defined in KDF for message 2 |
+ n = 1 +
| see KDF for associated data |
+ +
| |
+----+----+----+----+----+----+----+----+
| |
+ Length specified in message 1 +
| |
+ ChaChaPoly frame +
| Encrypted and authenticated |
+ +
| Alice RouterInfo |
+ using block format 2 +
| Alice Options (optional) |
+ using block format 1 +
| Arbitrary padding |
+ using block format 254 +
| |
+ +
| k defined in KDF for message 3 part 2 |
+ n = 0 +
| see KDF for associated data |
~ . . . ~
| |
+----+----+----+----+----+----+----+----+
S :: 32 bytes, ChaChaPoly encrypted Alice's X25519 static key, little endian
inside 48 byte ChaChaPoly frame
Unverschlüsselte Daten (Poly1305 Auth-Tags nicht angezeigt):
+----+----+----+----+----+----+----+----+
| |
+ +
| S |
+ Alice static key +
| (32 bytes) |
+ +
| |
+ +
+----+----+----+----+----+----+----+----+
| |
+ +
| |
+ +
| Alice RouterInfo block |
~ . . . ~
| |
+----+----+----+----+----+----+----+----+
| |
+ Optional Options block +
| |
~ . . . ~
| |
+----+----+----+----+----+----+----+----+
| |
+ Optional Padding block +
| |
~ . . . ~
| |
+----+----+----+----+----+----+----+----+
S :: 32 bytes, Alice's X25519 static key, little endian
1) Online DPI
Bob muss die übliche Router Info-Validierung durchführen. Stelle sicher, dass der Signaturtyp unterstützt wird, verifiziere die Signatur, verifiziere dass der Zeitstempel innerhalb der Grenzen liegt, und führe alle anderen notwendigen Prüfungen durch.
Bob muss überprüfen, dass Alices statischer Schlüssel, der im ersten Frame empfangen wurde, mit dem statischen Schlüssel in der Router Info übereinstimmt. Bob muss zunächst in der Router Info nach einer NTCP oder NTCP2 Router Address mit einer passenden Version (v) Option suchen. Siehe die Abschnitte Published Router Info und Unpublished Router Info unten.
Wenn Bob eine ältere Version von Alices RouterInfo in seiner netDb hat, überprüfen, dass der statische Schlüssel in der Router-Info in beiden gleich ist, falls vorhanden, und wenn die ältere Version weniger als XXX alt ist (siehe Schlüssel-Rotationszeit unten)
Bob muss hier validieren, dass Alices statischer Schlüssel ein gültiger Punkt auf der Kurve ist.
Optionen sollten enthalten sein, um Padding-Parameter zu spezifizieren.
Bei jedem Fehler, einschließlich AEAD-, RI-, DH-, Zeitstempel- oder Schlüssel-Validierungsfehlern, muss Bob die weitere Nachrichtenverarbeitung stoppen und die Verbindung ohne Antwort schließen. Dies sollte ein abnormaler Verbindungsabbruch sein (TCP RST).
Um ein schnelles Handshaking zu ermöglichen, müssen Implementierungen sicherstellen, dass Alice den gesamten Inhalt der dritten Nachricht puffert und dann auf einmal überträgt, einschließlich beider AEAD-Frames. Dies erhöht die Wahrscheinlichkeit, dass die Daten in einem einzigen TCP- Paket enthalten sind (es sei denn, sie werden vom Betriebssystem oder Middleboxes segmentiert) und von Bob auf einmal empfangen werden. Dies dient auch der Effizienz und soll die Wirksamkeit des zufälligen Paddings gewährleisten.
Message 3 Teil 2 Frame-Länge: Die Länge dieses Frames (einschließlich MAC) wird von Alice in Nachricht 1 gesendet. Siehe diese Nachricht für wichtige Hinweise zur Bereitstellung von ausreichend Platz für Padding.
Message 3 Teil 2 Frame-Inhalt: Das Format dieses Frames ist dasselbe wie das Format der Datenphase-Frames, außer dass die Länge des Frames von Alice in Message 1 gesendet wird. Siehe unten für das Datenphase-Frame-Format. Der Frame muss 1 bis 3 Blöcke in der folgenden Reihenfolge enthalten:
- Alices Router Info Block (erforderlich)
- Options Block (optional)
- Padding Block (optional) Dieser Frame darf niemals einen anderen Block-Typ enthalten.
Message 3 Teil 2 Padding ist nicht erforderlich, wenn Alice einen Datenphase-Frame (optional mit Padding) an das Ende von Message 3 anhängt und beide auf einmal sendet, da es einem Beobachter als ein großer Byte-Stream erscheinen wird. Da Alice im Allgemeinen, aber nicht immer, eine I2NP-Nachricht an Bob zu senden hat (deshalb hat sie sich mit ihm verbunden), ist dies die empfohlene Implementierung, für Effizienz und um die Wirksamkeit des zufälligen Paddings sicherzustellen.
Gesamtlänge beider Message 3 AEAD-Frames (Teil 1 und 2) beträgt 65535 Bytes; Teil 1 ist 48 Bytes, daher beträgt die maximale Frame-Länge von Teil 2 65487; maximale Plaintext-Länge von Teil 2 ohne MAC beträgt 65471.
Key Derivation Function (KDF) (for data phase)
Die Datenphase verwendet eine Eingabe für zugehörige Daten mit der Länge null.
Die KDF generiert zwei Chiffrierschlüssel k_ab und k_ba aus dem Verkettungsschlüssel ck, unter Verwendung von HMAC-SHA256(key, data) wie in RFC-2104 definiert. Dies ist die Split()-Funktion, genau wie in der Noise-Spezifikation definiert.
ck = from handshake phase
// k_ab, k_ba = HKDF(ck, zerolen)
// ask_master = HKDF(ck, zerolen, info="ask")
// zerolen is a zero-length byte array
temp_key = HMAC-SHA256(ck, zerolen)
// overwrite the chaining key in memory, no longer needed
ck = (all zeros)
// Output 1
// cipher key, for Alice transmits to Bob (Noise doesn't make clear which is which, but Java code does)
k_ab = HMAC-SHA256(temp_key, byte(0x01)).
// Output 2
// cipher key, for Bob transmits to Alice (Noise doesn't make clear which is which, but Java code does)
k_ba = HMAC-SHA256(temp_key, k_ab || byte(0x02)).
KDF for SipHash for length field:
Generate an Additional Symmetric Key (ask) for SipHash
SipHash uses two 8-byte keys (big endian) and 8 byte IV for first data.
// "ask" is 3 bytes, US-ASCII, no null termination
ask_master = HMAC-SHA256(temp_key, "ask" || byte(0x01))
// sip_master = HKDF(ask_master, h || "siphash")
// "siphash" is 7 bytes, US-ASCII, no null termination
// overwrite previous temp_key in memory
// h is from KDF for message 3 part 2
temp_key = HMAC-SHA256(ask_master, h || "siphash")
// overwrite ask_master in memory, no longer needed
ask_master = (all zeros)
sip_master = HMAC-SHA256(temp_key, byte(0x01))
Alice to Bob SipHash k1, k2, IV:
// sipkeys_ab, sipkeys_ba = HKDF(sip_master, zerolen)
// overwrite previous temp_key in memory
temp_key = HMAC-SHA256(sip_master, zerolen)
// overwrite sip_master in memory, no longer needed
sip_master = (all zeros)
sipkeys_ab = HMAC-SHA256(temp_key, byte(0x01)).
sipk1_ab = sipkeys_ab[0:7], little endian
sipk2_ab = sipkeys_ab[8:15], little endian
sipiv_ab = sipkeys_ab[16:23]
Bob to Alice SipHash k1, k2, IV:
sipkeys_ba = HMAC-SHA256(temp_key, sipkeys_ab || byte(0x02)).
sipk1_ba = sipkeys_ba[0:7], little endian
sipk2_ba = sipkeys_ba[8:15], little endian
sipiv_ba = sipkeys_ba[16:23]
// overwrite the temp_key in memory, no longer needed
temp_key = (all zeros)
4) Data Phase
Noise-Payload: Wie unten definiert, einschließlich zufälliger Padding Non-Noise-Payload: keine
Beginnend mit dem 2. Teil von Nachricht 3 befinden sich alle Nachrichten innerhalb eines authentifizierten und verschlüsselten ChaChaPoly-“Frames” mit einer vorangestellten zwei-Byte-verschleierten Länge. Alle Padding-Daten befinden sich innerhalb des Frames. Innerhalb des Frames befindet sich ein Standardformat mit null oder mehr “Blöcken”. Jeder Block hat einen Ein-Byte-Typ und eine Zwei-Byte-Länge. Typen umfassen Datum/Zeit, I2NP-Nachricht, Optionen, Terminierung und Padding.
Hinweis: Bob kann, ist aber nicht verpflichtet, seine RouterInfo als erste Nachricht an Alice in der Datenphase zu senden.
(Payload-Sicherheitseigenschaften)
XK(s, rs): Authentication Confidentiality
<- 2 5
-> 2 5
Authentication: 2.
Sender authentication resistant to key-compromise impersonation (KCI).
The sender authentication is based on an ephemeral-static DH ("es" or "se")
between the sender's static key pair and the recipient's ephemeral key pair.
Assuming the corresponding private keys are secure, this authentication cannot be forged.
Confidentiality: 5.
Encryption to a known recipient, strong forward secrecy.
This payload is encrypted based on an ephemeral-ephemeral DH as well as
an ephemeral-static DH with the recipient's static key pair.
Assuming the ephemeral private keys are secure, and the recipient is not being actively impersonated
by an attacker that has stolen its static private key, this payload cannot be decrypted.
2) Offline-DPI
Für Effizienz und um die Identifikation des Längenfelds zu minimieren, müssen Implementierungen sicherstellen, dass der Sender die gesamten Inhalte von Datennachrichten auf einmal puffert und dann weiterleitet, einschließlich des Längenfelds und des AEAD-Frames. Dies erhöht die Wahrscheinlichkeit, dass die Daten in einem einzigen TCP-Paket enthalten sind (es sei denn, sie werden vom Betriebssystem oder Middleboxen segmentiert) und von der anderen Partei auf einmal empfangen werden. Dies dient ebenfalls der Effizienz und um die Wirksamkeit des zufälligen Paddings zu gewährleisten.
Der Router kann wählen, die Sitzung bei einem AEAD-Fehler zu beenden, oder kann weiterhin versuchen zu kommunizieren. Falls er fortsetzt, sollte der Router nach wiederholten Fehlern beenden.
SipHash obfuscated length
Referenz: SipHash
Sobald beide Seiten den Handshake abgeschlossen haben, übertragen sie Nutzdaten, die dann in ChaChaPoly-“Frames” verschlüsselt und authentifiziert werden.
Jeder Frame wird von einer zwei-Byte-Länge im Big-Endian-Format vorangestellt. Diese Länge gibt die Anzahl der verschlüsselten Frame-Bytes an, die folgen, einschließlich des MAC. Um zu vermeiden, dass identifizierbare Längenfelder im Stream übertragen werden, wird die Frame-Länge durch XOR-Verknüpfung mit einer Maske verschleiert, die von SipHash abgeleitet wird, wie sie aus der KDF der Datenphase initialisiert wurde. Beachten Sie, dass die beiden Richtungen eindeutige SipHash-Schlüssel und IVs aus der KDF haben.
sipk1, sipk2 = The SipHash keys from the KDF. (two 8-byte long integers)
IV[0] = sipiv = The SipHash IV from the KDF. (8 bytes)
length is big endian.
For each frame:
IV[n] = SipHash-2-4(sipk1, sipk2, IV[n-1])
Mask[n] = First 2 bytes of IV[n]
obfuscatedLength = length ^ Mask[n]
The first length output will be XORed with with IV[1].
Der Empfänger verfügt über die identischen SipHash-Schlüssel und IV. Die Dekodierung der Länge erfolgt durch Ableitung der Maske, die zur Verschleierung der Länge verwendet wird, und XOR-Verknüpfung des gekürzten Digest, um die Länge des Frames zu erhalten. Die Frame-Länge ist die Gesamtlänge des verschlüsselten Frames einschließlich des MAC.
Zukünftige Arbeiten
- Wenn Sie eine SipHash-Bibliotheksfunktion verwenden, die eine unsigned long integer zurückgibt, verwenden Sie die beiden niederwertigsten Bytes als Mask. Konvertieren Sie die long integer zum nächsten IV als little endian.
Authentifizierte Verschlüsselung
+----+----+----+----+----+----+----+----+
|obf size | |
+----+----+ +
| |
+ ChaChaPoly frame +
| Encrypted and authenticated |
+ key is k_ab for Alice to Bob +
| key is k_ba for Bob to Alice |
+ as defined in KDF for data phase +
| n starts at 0 and increments |
+ for each frame in that direction +
| no associated data |
+ 16 bytes minimum +
| |
~ . . . ~
| |
+----+----+----+----+----+----+----+----+
obf size :: 2 bytes length obfuscated with SipHash
when de-obfuscated: 16 - 65535
Minimum size including length field is 18 bytes.
Maximum size including length field is 65537 bytes.
Obfuscated length is 2 bytes.
Maximum ChaChaPoly frame is 65535 bytes.
ChaCha20/Poly1305
Es gibt null oder mehr Blöcke im verschlüsselten Frame. Jeder Block enthält eine Ein-Byte-Kennung, eine Zwei-Byte-Länge und null oder mehr Datenbytes.
Für Erweiterbarkeit müssen Empfänger Blöcke mit unbekannten Identifikatoren ignorieren und sie als Padding behandeln.
Verschlüsselte Daten haben eine maximale Größe von 65535 Bytes, einschließlich eines 16-Byte-Authentifizierungsheaders, sodass die maximalen unverschlüsselten Daten 65519 Bytes betragen.
(Poly1305 Auth-Tag nicht angezeigt):
+----+----+----+----+----+----+----+----+
|blk | size | data |
+----+----+----+ +
| |
~ . . . ~
| |
+----+----+----+----+----+----+----+----+
|blk | size | data |
+----+----+----+ +
| |
~ . . . ~
| |
+----+----+----+----+----+----+----+----+
~ . . . ~
blk :: 1 byte
0 for datetime
1 for options
2 for RouterInfo
3 for I2NP message
4 for termination
224-253 reserved for experimental features
254 for padding
255 reserved for future extension
size :: 2 bytes, big endian, size of data to follow, 0 - 65516
data :: the data
Maximum ChaChaPoly frame is 65535 bytes.
Poly1305 tag is 16 bytes
Maximum total block size is 65519 bytes
Maximum single block size is 65519 bytes
Block type is 1 byte
Block length is 2 bytes
Maximum single block data size is 65516 bytes.
Block Ordering Rules
In der Handshake-Nachricht 3 Teil 2 muss die Reihenfolge sein: RouterInfo, gefolgt von Options falls vorhanden, gefolgt von Padding falls vorhanden. Keine anderen Blöcke sind erlaubt.
In der Datenphase ist die Reihenfolge nicht spezifiziert, außer für die folgenden Anforderungen: Padding, falls vorhanden, muss der letzte Block sein. Termination, falls vorhanden, muss der letzte Block außer Padding sein.
Es können mehrere I2NP-Blöcke in einem einzigen Frame vorhanden sein. Mehrere Padding-Blöcke sind in einem einzigen Frame nicht erlaubt. Andere Blocktypen werden wahrscheinlich nicht mehrere Blöcke in einem einzigen Frame haben, aber es ist nicht verboten.
AEAD-Fehlerbehandlung
Sonderfall für Zeitsynchronisation:
+----+----+----+----+----+----+----+
| 0 | 4 | timestamp |
+----+----+----+----+----+----+----+
blk :: 0
size :: 2 bytes, big endian, value = 4
timestamp :: Unix timestamp, unsigned seconds.
Wraps around in 2106
Key Derivation Function (KDF) (für Handshake-Nachricht 1)
Aktualisierte Optionen übergeben. Optionen umfassen: Min und max padding.
Der Optionsblock wird eine variable Länge haben.
+----+----+----+----+----+----+----+----+
| 1 | size |tmin|tmax|rmin|rmax|tdmy|
+----+----+----+----+----+----+----+----+
|tdmy| rdmy | tdelay | rdelay | |
~----+----+----+----+----+----+----+ ~
| more_options |
~ . . . ~
| |
+----+----+----+----+----+----+----+----+
blk :: 1
size :: 2 bytes, big endian, size of options to follow, 12 bytes minimum
tmin, tmax, rmin, rmax :: requested padding limits
tmin and rmin are for desired resistance to traffic analysis.
tmax and rmax are for bandwidth limits.
tmin and tmax are the transmit limits for the router sending this options block.
rmin and rmax are the receive limits for the router sending this options block.
Each is a 4.4 fixed-point float representing 0 to 15.9375
(or think of it as an unsigned 8-bit integer divided by 16.0).
This is the ratio of padding to data. Examples:
Value of 0x00 means no padding
Value of 0x01 means add 6 percent padding
Value of 0x10 means add 100 percent padding
Value of 0x80 means add 800 percent (8x) padding
Alice and Bob will negotiate the minimum and maximum in each direction.
These are guidelines, there is no enforcement.
Sender should honor receiver's maximum.
Sender may or may not honor receiver's minimum, within bandwidth constraints.
tdmy: Max dummy traffic willing to send, 2 bytes big endian, bytes/sec average
rdmy: Requested dummy traffic, 2 bytes big endian, bytes/sec average
tdelay: Max intra-message delay willing to insert, 2 bytes big endian, msec average
rdelay: Requested intra-message delay, 2 bytes big endian, msec average
Padding distribution specified as additional parameters?
Random delay specified as additional parameters?
more_options :: Format TBD
1) SessionRequest
- Das Optionsformat ist noch zu bestimmen.
- Die Optionsverhandlung ist noch zu bestimmen.
RouterInfo
Übertrage Alices RouterInfo an Bob. Wird in Handshake-Nachricht 3 Teil 2 verwendet. Übertrage Alices RouterInfo an Bob oder Bobs an Alice. Wird optional in der Datenphase verwendet.
+----+----+----+----+----+----+----+----+
| 2 | size |flg | RouterInfo |
+----+----+----+----+ +
| (Alice RI in handshake msg 3 part 2) |
~ (Alice, Bob, or third-party ~
| RI in data phase) |
~ . . . ~
| |
+----+----+----+----+----+----+----+----+
blk :: 2
size :: 2 bytes, big endian, size of flag + router info to follow
flg :: 1 byte flags
bit order: 76543210
bit 0: 0 for local store, 1 for flood request
bits 7-1: Unused, set to 0 for future compatibility
routerinfo :: Alice's or Bob's RouterInfo
Notes
Wenn in der Datenphase verwendet, soll der Empfänger (Alice oder Bob) validieren, dass es sich um denselben Router Hash handelt, wie ursprünglich gesendet (für Alice) oder gesendet an (für Bob). Dann als lokale I2NP DatabaseStore Message behandeln. Signatur validieren, neueren Zeitstempel validieren und in der lokalen netDb speichern. Wenn das Flag-Bit 0 gleich 1 ist und die empfangende Partei ein floodfill ist, als DatabaseStore Message mit einem Reply-Token ungleich null behandeln und an die nächstgelegenen floodfills weiterleiten.
Die Router Info ist NICHT mit gzip komprimiert (im Gegensatz zu einer DatabaseStore Message, wo sie es ist)
Flooding darf nicht angefordert werden, es sei denn, es sind veröffentlichte RouterAddresses in der RouterInfo vorhanden. Der empfangende Router darf die RouterInfo nicht flooden, es sei denn, es sind veröffentlichte RouterAddresses darin enthalten.
Implementer müssen sicherstellen, dass beim Lesen eines Blocks fehlerhafte oder bösartige Daten nicht dazu führen, dass Lesevorgänge in den nächsten Block überlaufen.
Dieses Protokoll stellt keine Bestätigung bereit, dass die RouterInfo empfangen, gespeichert oder geflutet wurde (weder in der Handshake- noch in der Datenphase). Falls eine Bestätigung gewünscht wird und der Empfänger ein floodfill ist, sollte der Sender stattdessen eine Standard I2NP DatabaseStoreMessage mit einem Reply-Token senden.
Issues
Könnte auch in der Datenphase verwendet werden, anstelle einer I2NP DatabaseStoreMessage. Zum Beispiel könnte Bob sie verwenden, um die Datenphase zu beginnen.
Ist es erlaubt, dass dies die RI für andere Router als den Originator enthält, als allgemeiner Ersatz für DatabaseStoreMessages, z.B. für das Flooding durch floodfills?
Key Derivation Function (KDF) (für Handshake-Nachricht 2 und Nachricht 3 Teil 1)
Eine einzelne I2NP-Nachricht mit einem modifizierten Header. I2NP-Nachrichten dürfen nicht über Blöcke oder über ChaChaPoly-Frames fragmentiert werden.
Dies verwendet die ersten 9 Bytes aus dem Standard-NTCP I2NP-Header und entfernt die letzten 7 Bytes des Headers wie folgt: kürzt die Ablaufzeit von 8 auf 4 Bytes, entfernt die 2-Byte-Länge (verwende die Blockgröße - 9) und entfernt die Ein-Byte-SHA256-Prüfsumme.
+----+----+----+----+----+----+----+----+
| 3 | size |type| msg id |
+----+----+----+----+----+----+----+----+
| short exp | message |
+----+----+----+----+ +
| |
~ . . . ~
| |
+----+----+----+----+----+----+----+----+
blk :: 3
size :: 2 bytes, big endian, size of type + msg id + exp + message to follow
I2NP message body size is (size - 9).
type :: 1 byte, I2NP msg type, see I2NP spec
msg id :: 4 bytes, big endian, I2NP message ID
short exp :: 4 bytes, big endian, I2NP message expiration, Unix timestamp, unsigned seconds.
Wraps around in 2106
message :: I2NP message body
Notes
- Implementierer müssen sicherstellen, dass beim Lesen eines Blocks fehlerhafte oder bösartige Daten nicht dazu führen, dass Lesevorgänge in den nächsten Block überlaufen.
2) SessionCreated
Noise empfiehlt eine explizite Beendigungsnachricht. Das ursprüngliche NTCP hat keine. Verbindung trennen. Dies muss der letzte Nicht-Padding-Block im Frame sein.
+----+----+----+----+----+----+----+----+
| 4 | size | valid data frames |
+----+----+----+----+----+----+----+----+
received | rsn| addl data |
+----+----+----+----+ +
~ . . . ~
+----+----+----+----+----+----+----+----+
blk :: 4
size :: 2 bytes, big endian, value = 9 or more
valid data frames received :: The number of valid AEAD data phase frames received
(current receive nonce value)
0 if error occurs in handshake phase
8 bytes, big endian
rsn :: reason, 1 byte:
0: normal close or unspecified
1: termination received
2: idle timeout
3: router shutdown
4: data phase AEAD failure
5: incompatible options
6: incompatible signature type
7: clock skew
8: padding violation
9: AEAD framing error
10: payload format error
11: message 1 error
12: message 2 error
13: message 3 error
14: intra-frame read timeout
15: RI signature verification fail
16: s parameter missing, invalid, or mismatched in RouterInfo
17: banned
addl data :: optional, 0 or more bytes, for future expansion, debugging,
or reason text.
Format unspecified and may vary based on reason code.
Notes
Nicht alle Gründe werden möglicherweise tatsächlich verwendet, implementierungsabhängig. Handshake-Fehler führen im Allgemeinen zu einem Schließen mit TCP RST. Siehe Hinweise in den Handshake-Nachrichtenbereichen oben. Zusätzlich aufgeführte Gründe dienen der Konsistenz, Protokollierung, Fehlersuche oder für den Fall von Richtlinienänderungen.
Padding
Dies dient der Auffüllung innerhalb von AEAD-Frames. Die Auffüllung für Nachrichten 1 und 2 erfolgt außerhalb von AEAD-Frames. Die gesamte Auffüllung für Nachricht 3 und die Datenphase erfolgt innerhalb von AEAD-Frames.
Padding innerhalb von AEAD sollte ungefähr den ausgehandelten Parametern entsprechen. Bob hat seine angeforderten tx/rx min/max Parameter in Nachricht 2 gesendet. Alice hat ihre angeforderten tx/rx min/max Parameter in Nachricht 3 gesendet. Aktualisierte Optionen können während der Datenphase gesendet werden. Siehe Optionsblock-Informationen oben.
Falls vorhanden, muss dies der letzte Block im Frame sein.
+----+----+----+----+----+----+----+----+
|254 | size | padding |
+----+----+----+ +
| |
~ . . . ~
| |
+----+----+----+----+----+----+----+----+
blk :: 254
size :: 2 bytes, big endian, size of padding to follow
padding :: random data
Notes
- Padding-Strategien noch zu bestimmen.
- Minimales Padding noch zu bestimmen.
- Reine Padding-Frames sind erlaubt.
- Padding-Standardwerte noch zu bestimmen.
- Siehe options-Block für die Aushandlung von Padding-Parametern
- Siehe options-Block für min/max Padding-Parameter
- Noise begrenzt Nachrichten auf 64KB. Falls mehr Padding notwendig ist, mehrere Frames senden.
- Router-Antwort bei Verletzung des ausgehandelten Paddings ist implementierungsabhängig.
Other block types
Implementierungen sollten unbekannte Blocktypen für die Vorwärtskompatibilität ignorieren, außer in Nachricht 3 Teil 2, wo unbekannte Blöcke nicht erlaubt sind.
Future work
- Die Padding-Länge soll entweder nachrichtenbasiert entschieden werden unter Berücksichtigung von Schätzungen der Längenverteilung, oder es sollten zufällige Verzögerungen hinzugefügt werden. Diese Gegenmaßnahmen sollen zur Widerstandsfähigkeit gegen DPI beitragen, da Nachrichtengrößen andernfalls verraten würden, dass I2P-Traffic über das Transportprotokoll übertragen wird. Das exakte Padding-Schema ist ein Bereich zukünftiger Arbeit, Anhang A liefert weitere Informationen zu diesem Thema.
5) Termination
Verbindungen können durch normales oder abnormales Schließen des TCP-Sockets beendet werden, oder, wie Noise empfiehlt, durch eine explizite Beendigungsnachricht. Die explizite Beendigungsnachricht ist in der oben beschriebenen Datenphase definiert.
Bei jeder normalen oder abnormalen Beendigung sollten Router alle im Arbeitsspeicher befindlichen ephemeren Daten löschen, einschließlich Handshake-Ephemeralschlüssel, symmetrische Kryptoschlüssel und zugehörige Informationen.
Published Router Info
Verschlüsselung für Handshake-Nachricht 3 Teil 1, unter Verwendung von Nachricht 2 KDF)
Die veröffentlichte RouterAddress (Teil der RouterInfo) wird eine Protokollkennung von entweder “NTCP” oder “NTCP2” haben.
Die RouterAddress muss “host” und “port” Optionen enthalten, wie im aktuellen NTCP2 Protokoll.
Die RouterAddress muss drei Optionen enthalten, um NTCP2-Unterstützung anzuzeigen:
s=(Base64 key) Der aktuelle statische öffentliche Noise-Schlüssel (s) für diese RouterAddress. Base 64 kodiert unter Verwendung des Standard-I2P-Base-64-Alphabets. 32 Bytes in binärer Form, 44 Bytes als Base 64 kodiert, little-endian X25519 öffentlicher Schlüssel.
i=(Base64 IV) Der aktuelle IV zum Verschlüsseln des X-Wertes in Nachricht 1 für diese RouterAddress. Base 64 kodiert unter Verwendung des Standard-I2P Base 64 Alphabets. 16 Bytes binär, 24 Bytes als Base 64 kodiert, big-endian.
v=2 Die aktuelle Version (2). Wenn als “NTCP” veröffentlicht, ist zusätzliche Unterstützung für Version 1 impliziert. Unterstützung für zukünftige Versionen erfolgt mit durch Komma getrennten Werten, z.B. v=2,3 Die Implementierung sollte Kompatibilität prüfen, einschließlich mehrerer Versionen, falls ein Komma vorhanden ist. Durch Komma getrennte Versionen müssen in numerischer Reihenfolge stehen.
Alice muss überprüfen, dass alle drei Optionen vorhanden und gültig sind, bevor sie eine Verbindung über das NTCP2-Protokoll herstellt.
Wenn als “NTCP” mit den Optionen “s”, “i” und “v” veröffentlicht, muss der Router eingehende Verbindungen auf diesem Host und Port für sowohl NTCP- als auch NTCP2-Protokolle akzeptieren und die Protokollversion automatisch erkennen.
Wenn als “NTCP2” mit den Optionen “s”, “i” und “v” veröffentlicht, akzeptiert der Router eingehende Verbindungen auf diesem Host und Port nur für das NTCP2-Protokoll.
Wenn ein router sowohl NTCP1- als auch NTCP2-Verbindungen unterstützt, aber keine automatische Versionserkennung für eingehende Verbindungen implementiert, muss er sowohl “NTCP”- als auch “NTCP2”-Adressen bewerben und die NTCP2-Optionen nur in der “NTCP2”-Adresse einschließen. Der router sollte einen niedrigeren Kostenwert (höhere Priorität) in der “NTCP2”-Adresse als in der “NTCP”-Adresse setzen, damit NTCP2 bevorzugt wird.
Wenn mehrere NTCP2 RouterAddresses (entweder als “NTCP” oder “NTCP2”) in derselben RouterInfo veröffentlicht werden (für zusätzliche IP-Adressen oder Ports), müssen alle Adressen, die denselben Port angeben, identische NTCP2-Optionen und -Werte enthalten. Insbesondere müssen alle denselben statischen Schlüssel und iv enthalten.
Key Derivation Function (KDF) (für Handshake-Nachricht 3 Teil 2)
Wenn Alice ihre NTCP2-Adresse nicht veröffentlicht (als “NTCP” oder “NTCP2”) für eingehende Verbindungen, muss sie eine “NTCP2”-Router-Adresse veröffentlichen, die nur ihren statischen Schlüssel und die NTCP2-Version enthält, damit Bob den Schlüssel nach Erhalt von Alices RouterInfo in Nachricht 3 Teil 2 validieren kann.
s=(Base64 key) Wie oben für veröffentlichte Adressen definiert.
v=2 Wie oben für veröffentlichte Adressen definiert.
Diese router-Adresse wird keine “i”-, “host”- oder “port”-Optionen enthalten, da diese für ausgehende NTCP2-Verbindungen nicht erforderlich sind. Die veröffentlichten Kosten für diese Adresse sind nicht strikt von Bedeutung, da sie nur für eingehende Verbindungen ist; es kann jedoch für andere router hilfreich sein, wenn die Kosten höher (niedrigere Priorität) als bei anderen Adressen gesetzt werden. Der empfohlene Wert ist 14.
Alice kann auch einfach die Optionen “s” und “v” zu einer bereits veröffentlichten “NTCP”-Adresse hinzufügen.
3) SessionConfirmed
Aufgrund der Zwischenspeicherung von RouterInfos dürfen Router den statischen öffentlichen Schlüssel oder IV nicht rotieren, während der Router aktiv ist, unabhängig davon, ob in einer veröffentlichten Adresse oder nicht. Router müssen diesen Schlüssel und IV persistent speichern, um sie nach einem sofortigen Neustart wiederzuverwenden, damit eingehende Verbindungen weiterhin funktionieren und Neustartzeiten nicht preisgegeben werden. Router müssen die letzte Herunterfahrzeit persistent speichern oder anderweitig bestimmen, damit die vorherige Ausfallzeit beim Start berechnet werden kann.
Unter Berücksichtigung der Bedenken bezüglich der Preisgabe von Neustartzeiten können Router diesen Schlüssel oder IV beim Start rotieren, wenn der Router zuvor für einige Zeit heruntergefahren war (mindestens ein paar Stunden).
Falls der router veröffentlichte NTCP2 RouterAddresses (als NTCP oder NTCP2) hat, sollte die minimale Ausfallzeit vor einer Rotation viel länger sein, zum Beispiel einen Monat, es sei denn, die lokale IP-Adresse hat sich geändert oder der router führt ein “rekeys” durch.
Falls der Router veröffentlichte SSU RouterAddresses, aber nicht NTCP2 (als NTCP oder NTCP2) hat, sollte die minimale Ausfallzeit vor der Rotation länger sein, beispielsweise einen Tag, es sei denn, die lokale IP-Adresse hat sich geändert oder der Router führt ein “rekeys” durch. Dies gilt auch dann, wenn die veröffentlichte SSU-Adresse Introducer hat.
Wenn der Router keine veröffentlichten RouterAddresses (NTCP, NTCP2 oder SSU) hat, kann die minimale Ausfallzeit vor der Rotation nur zwei Stunden betragen, selbst wenn sich die IP-Adresse ändert, es sei denn, der Router führt ein “rekeys” durch.
Wenn der Router zu einem anderen Router Hash “rekeys”, sollte er auch einen neuen Noise-Schlüssel und IV generieren.
Implementierungen müssen sich bewusst sein, dass eine Änderung des statischen öffentlichen Schlüssels oder IV eingehende NTCP2-Verbindungen von Routern verhindert, die eine ältere RouterInfo zwischengespeichert haben. RouterInfo-Veröffentlichung, Tunnel-Peer-Auswahl (einschließlich sowohl OBGW als auch IB nächster Hop), Zero-Hop-Tunnel-Auswahl, Transport-Auswahl und andere Implementierungsstrategien müssen dies berücksichtigen.
IV-Rotation unterliegt identischen Regeln wie die Schlüsselrotation, außer dass IVs nur in veröffentlichten RouterAddresses vorhanden sind, sodass es keine IV für versteckte oder durch Firewalls geschützte Router gibt. Wenn sich etwas ändert (Version, Schlüssel, Optionen?), wird empfohlen, dass sich die IV ebenfalls ändert.
Hinweis: Die minimale Ausfallzeit vor der Neuverschlüsselung kann angepasst werden, um die Netzwerkgesundheit zu gewährleisten und zu verhindern, dass ein Router, der für eine moderate Zeitspanne ausgefallen war, erneut geseeded wird.
Identity Hiding
Bestreitbarkeit ist kein Ziel. Siehe Übersicht oben.
Jedem Pattern werden Eigenschaften zugewiesen, die die Vertraulichkeit beschreiben, die für den öffentlichen statischen Schlüssel des Initiators und für den öffentlichen statischen Schlüssel des Responders bereitgestellt wird. Die zugrundeliegenden Annahmen sind, dass ephemere private Schlüssel sicher sind und dass die Parteien den Handshake abbrechen, wenn sie einen statischen öffentlichen Schlüssel von der anderen Partei erhalten, dem sie nicht vertrauen.
Dieser Abschnitt betrachtet nur Identitätslecks durch statische öffentliche Schlüsselfelder in Handshakes. Natürlich könnten die Identitäten von Noise-Teilnehmern durch andere Mittel preisgegeben werden, einschließlich Payload-Feldern, Verkehrsanalyse oder Metadaten wie IP-Adressen.
Alice: (8) Verschlüsselt mit Forward Secrecy zu einer authentifizierten Partei.
Bob: (3) Nicht übertragen, aber ein passiver Angreifer kann Kandidaten für den privaten Schlüssel des Responders überprüfen und bestimmen, ob der Kandidat korrekt ist.
Bob veröffentlicht seinen statischen öffentlichen Schlüssel in der netDb. Alice könnte oder könnte nicht?
Issues
- Wenn Bob seinen statischen Schlüssel ändert, könnte auf ein “XX”-Muster zurückgegriffen werden?
Noise Protocol Framework
Wenn als “NTCP” veröffentlicht, muss der router automatisch die Protokollversion für eingehende Verbindungen erkennen.
Diese Erkennung ist implementierungsabhängig, aber hier ist eine allgemeine Anleitung.
Um die Version einer eingehenden NTCP-Verbindung zu erkennen, geht Bob wie folgt vor:
Warten auf mindestens 64 Bytes (minimale NTCP2 Nachricht 1 Größe)
Wenn die initial empfangenen Daten 288 oder mehr Bytes betragen, ist die eingehende Verbindung Version 1.
Wenn weniger als 288 Bytes, dann entweder
Kurz auf weitere Daten warten (gute Strategie vor weit verbreiteter NTCP2-Einführung), falls mindestens 288 insgesamt empfangen wurden, ist es NTCP 1.
Versuche die ersten Dekodierungsstufen als Version 2, falls dies fehlschlägt, warte kurz auf weitere Daten (gute Strategie nach weit verbreiteter NTCP2-Einführung)
- Decrypt the first 32 bytes (the X key) of the SessionRequest packet using AES-256 with key RH_B. - Verify a valid point on the curve. If it fails, wait a short time for more data for NTCP 1 - Verify the AEAD frame. If it fails, wait a short time for more data for NTCP 1
Beachten Sie, dass Änderungen oder zusätzliche Strategien empfohlen werden können, wenn wir aktive TCP-Segmentierungsangriffe auf NTCP 1 erkennen.
Um eine schnelle Versionserkennung und Handshaking zu ermöglichen, müssen Implementierungen sicherstellen, dass Alice den gesamten Inhalt der ersten Nachricht puffert und dann auf einmal überträgt, einschließlich des Paddings. Dies erhöht die Wahrscheinlichkeit, dass die Daten in einem einzigen TCP-Paket enthalten sind (es sei denn, sie werden vom OS oder Middleboxes segmentiert) und von Bob auf einmal empfangen werden. Dies dient auch der Effizienz und um die Wirksamkeit des zufälligen Paddings sicherzustellen. Dies gilt sowohl für NTCP- als auch für NTCP2-Handshakes.
Erweiterungen des Frameworks
Wenn Alice und Bob beide NTCP2 unterstützen, sollte Alice sich mit NTCP2 verbinden.
Wenn Alice aus irgendeinem Grund nicht über NTCP2 eine Verbindung zu Bob herstellen kann, schlägt die Verbindung fehl. Alice darf nicht mit NTCP 1 einen erneuten Versuch unternehmen.
Fallback auf XX-Muster, wenn Bob seine Schlüssel ändert? Dies würde ein vorangestelltes Typ-Byte erfordern?
“Fall forward” auf KK-Muster wenn Alice sich wieder verbindet, angenommen Bob hat noch ihren statischen Schlüssel? Das spart keine Round Trips und verwendet 4 DH-Runden verglichen mit 3 für XK. Wahrscheinlich nicht.
KK(s, rs):
-> s
<- s
...
-> e, es, ss
<- e, ee, se
Neue kryptographische Grundbausteine für I2P
Dieser Abschnitt behandelt einen Angriff auf typische Padding-Schemata, der es Angreifern ermöglicht, die Wahrscheinlichkeitsverteilung der Länge der ungepadeten Nachrichten zu ermitteln, indem sie nur die Länge der gepadeten Nachrichten beobachten. Sei N eine Zufallsvariable, die die Anzahl der ungepadeten Bytes beschreibt, und P entsprechend für die Anzahl der Padding-Bytes. Die Gesamtnachrichtengröße ist dann N + P.
Nehmen wir an, dass für eine ungefüllte Größe von n mindestens P_min(n) >= 0 und höchstens P_max(n) >= P_min(n) Bytes an Padding in einem Padding-Schema hinzugefügt werden. Das offensichtliche Schema verwendet Padding der Länge P, die gleichmäßig zufällig gewählt wird:
Pr[P = p | N = n] = 1 / (P_max(n) - P_min(n)) if P_min(n) <= p <= P_max(n),
0 otherwise.
Ein naives Padding-Schema würde einfach sicherstellen, dass die Größe der gepaddetenBotschaft N_max nicht überschreitet:
P_max(n) = N_max - n, n <= N_max
P_min(n) = 0.
Dies führt jedoch zu einem Informationsleck über die ungefüllte Länge.
Ein Angreifer kann leicht Pr[x <= N + P <= y] schätzen, beispielsweise mittels eines Histogramms.
- Daraus kann er auch versuchen,
Pr[n_1 <= N <= n_2]zu schätzen, tatsächlich:
Pr[N + P = m] = Σ_n Pr[N = n] Pr[P = m - n | N = n].
Im naiven Schema,
Pr[N + P = m] = Σ_{n <= m} Pr[N = n] / (N_max - n).
Es ist ziemlich offensichtlich, wie es schon vor der obigen Berechnung war, dass dies Informationen über Pr[N = n] preisgibt: wenn die Länge der Pakete fast immer mehr als m beträgt, dann wird N + P <= m fast nie beobachtet werden. Das ist jedoch nicht das größte Problem, obwohl die Möglichkeit, die minimale Nachrichtenlänge zu beobachten, an sich als Problem betrachtet werden kann.
Ein größeres Problem ist, dass es möglich ist, Pr[N = n] exakt zu bestimmen:
Pr[N + P = m] - Pr[N + P = m-1] = Pr[N = m] / (N_max - m),
das ist
Pr[N = n] = (N_max - n)(Pr[N + P = n] - Pr[N + P = n - 1])
Um NTCP2 zu unterscheiden, kann der Angreifer dann eine der folgenden Methoden verwenden:
Schätze
Pr[kB <= N <= (k + 1)B - 1]für positive ganze Zahlen k. Es wird bei NTCP2 immer null sein.Schätze
Pr[N = kB]und vergleiche mit einem Standard-I2P-Profil.
Dieser einfache Angriff zerstört daher teilweise den Zweck des Paddings, welches versucht, die Größenverteilung der ungepaddeten Nachrichten zu verschleiern. Die Anzahl der Nachrichten, die der Angreifer beobachten muss, um das Protokoll zu unterscheiden, hängt von der gewünschten Genauigkeit und von den minimalen und maximalen ungepaddeten Nachrichtengrößen ab, die in der Praxis auftreten. Zu beachten ist, dass es für den Angreifer einfach ist, viele Nachrichten zu sammeln, da er den gesamten Verkehr nutzen kann, der von und zu dem bestimmten Port gesendet wird, den das Ziel verwendet.
In einigen Formen (z.B. Schätzung von Pr[kB <= N <= (k + 1)B - 1]) erfordert der Angriff nur wenige Bytes Speicher (eine einzige Ganzzahl ist ausreichend) und es könnte argumentiert werden, dass ein solcher Angriff in vielen etwas fortgeschritteneren, aber dennoch standardmäßigen DPI-Frameworks enthalten sein könnte.
Dieser Vorschlag schlägt vor, eine der folgenden Gegenmaßnahmen zu verwenden:
Entwickle ein alternatives Padding-Schema, das die (geschätzte) Verteilung von N berücksichtigt, indem eine nicht-uniforme Padding-Längen-Verteilung verwendet wird. Ein gutes Padding-Schema würde wahrscheinlich die Pflege eines Histogramms der Anzahl von Blöcken pro Nachricht erfordern.
Füge zufällige Verzögerungen zwischen (zufällig dimensionierten) Fragmenten von Nachrichten hinzu.
Die zweite Option wird im Allgemeinen bevorzugt, da sie gleichzeitig als Gegenmaßnahme gegen Datenflussanalyse verwendet werden kann. Solche Verzögerungen können jedoch außerhalb des Geltungsbereichs des NTCP2-Protokolls liegen, sodass stattdessen die erste Option, die auch einfacher zu implementieren ist, bevorzugt werden könnte.
Schätzung des Verarbeitungsoverheads
Zeitbasierte DPI-Resistenz (Zeitabstände/Verzögerungen zwischen Nachrichten können implementierungsabhängig sein; Verzögerungen innerhalb von Nachrichten können an jedem Punkt eingeführt werden, einschließlich vor dem Senden der zufälligen Auffüllung, zum Beispiel). Künstliche Verzögerungen (was obfs4 IAT oder Inter-Arrival Time nennt) sind unabhängig vom Protokoll selbst.