Diese Übersetzung wurde mittels maschinellem Lernen erstellt und ist möglicherweise nicht 100% korrekt. Englische Version anzeigen

NTCP 2

Proposal 111
Geschlossen
Author EinMByte, orignal, psi, str4d, zzz
Created 2014-02-13
Last Updated 2019-08-13
Target Version 0.9.36
Implemented In 0.9.36
Supercedes: 106

Hinweis

Der Vorschlagsphase ist abgeschlossen. Siehe SPEC für die offizielle Spezifikation. Dieser Vorschlag kann immer noch als Hintergrundinformation referenziert werden.

Übersicht

Dieser Vorschlag beschreibt ein authentifiziertes Schlüsselabstimmungsprotokoll, um die Widerstandsfähigkeit von NTCP gegen verschiedene Formen automatisierter Identifizierung und Angriffe zu verbessern.

Der Vorschlag ist wie folgt organisiert: Zunächst werden die Sicherheitsziele vorgestellt, gefolgt von einer Diskussion des grundlegenden Protokolls. Als Nächstes wird eine vollständige Spezifikation aller Protokollnachrichten gegeben. Schließlich werden Router-Adressen und Versionsidentifizierung diskutiert. Ein Anhang, der einen generischen Angriff auf gemeinsame Paddingschemata diskutiert, ist ebenfalls enthalten, sowie ein Anhang, der eine Reihe von Kandidaten für den authentifizierten Verschlüsselungsalgorithmus enthält.

Wie bei anderen I2P-Transporten ist NTCP2 ausschließlich für den Punkt-zu-Punkt-Transport (Router-zu-Router) von I2NP-Nachrichten definiert. Es handelt sich nicht um eine allgemeine Datenleitung.

Motivation

NTCP -Daten werden nach der ersten Nachricht (und die erste Nachricht erscheint als zufällige Daten) verschlüsselt, wodurch die Protokollidentifizierung durch “Payload-Analyse” verhindert wird. Es ist jedoch immer noch anfällig für Protokollidentifizierung durch “Flussanalyse”. Der Grund dafür ist, dass die ersten 4 Nachrichten (d. h. der Handschlag) eine feste Länge haben (288, 304, 448 und 48 Bytes).

Durch Hinzufügen von zufälligen Mengen an zufälligen Daten zu jeder der Nachrichten kann es viel schwieriger gemacht werden.

Die Autoren erkennen an, dass standardmäßige Sicherheitspraktiken die Verwendung eines bestehenden Protokolls wie TLS nahelegen würden, aber dies ist Prop104 und es gibt eigene Probleme. Wo immer angemessen, wurden “Zukunftsarbeiten”-Abschnitte hinzugefügt, um fehlende Funktionen oder Diskussionsthemen anzugeben.

Design-Ziele

  • Unterstützung von NTCP 1 und 2 auf einem einzigen Port, automatische Erkennung und Veröffentlichung als ein einziger “Transport” (d. h. Router-Adresse) im NetDB .

  • Veröffentlichung der Unterstützung für Version 1 nur, 2 nur oder 1+2 im NetDB in einem separaten Feld und Standardmäßige Verwendung von Version 1 nur (Binden der Versionsunterstützung nicht an eine bestimmte Router-Version)

  • Sicherstellen, dass alle Implementierungen (Java/i2pd/Kovri/go) die Version 2-Unterstützung (oder nicht) nach ihrem eigenen Zeitplan hinzufügen können

  • Hinzufügen von zufälligem Padding zu allen NTCP-Nachrichten, einschließlich Handschlag- und Daten-Nachrichten (d. h. Längen-Verwischung, damit alle Nachrichten nicht ein Vielfaches von 16 Bytes sind) Bereitstellen eines Mechanismus für beide Seiten, um Mindest- und Höchstwerte für das Padding und/oder die Paddingsverteilung anzufordern. Die Einzelheiten der Paddingsverteilung sind implementierungsabhängig und können im Protokoll selbst angegeben oder nicht angegeben werden.

  • Verwischen des Inhalts von Nachrichten, die nicht verschlüsselt sind (1 und 2), ausreichend, damit DPI-Boxen und AV-Signaturen sie nicht leicht klassifizieren können. Stellen Sie außerdem sicher, dass die Nachrichten, die an einen einzigen Peer oder eine Gruppe von Peers gesendet werden, keinen ähnlichen Muster von Bits aufweisen.

  • Beheben des Verlusts von Bits in DH aufgrund von Java-Format Ticket1112 , möglicherweise (wahrscheinlich?) durch Umstellung auf X25519.

  • Umstellung auf eine echte Schlüsselableitungs-Funktion (KDF) anstelle der Verwendung des DH-Ergebnisses als solche?

  • Hinzufügen von “Sondierungs-Widerstand” (wie es von Tor bezeichnet wird); dies umfasst Wiederholungs-Widerstand.

  • Beibehaltung der 2-Wege-authentifizierten Schlüsselaustausch (2W-AKE). 1W-AKE ist für unsere Anwendung nicht ausreichend.

  • Fortführung der Verwendung von variablen Typen, variabler Länge und Signaturen (aus dem veröffentlichten Router-Identitäts-Schlüssel) als Teil der Authentifizierung. Verlassen auf einen statischen öffentlichen Schlüssel, der im RouterInfo als weiterer Teil der Authentifizierung veröffentlicht wird.

  • Hinzufügen von Optionen/Version im Handschlag für zukünftige Erweiterbarkeit.

  • Hinzufügen von Widerstand gegen bösartige MitM-TCP-Segmentierung, wenn möglich.

  • Keine signifikante Erhöhung der für die Verbindungsaufnahme erforderlichen CPU-Leistung; wenn möglich, Reduzierung um ein Vielfaches.

  • Hinzufügen von Nachrichten-Authentifizierung (MAC), möglicherweise HMAC-SHA256 und Poly1305, und Entfernen des Adler-Prüfwerts.

  • Verkürzen und Vereinfachen des I2NP-Headers: Verkürzen der Ablaufzeit auf 4 Bytes, wie in SSU. Entfernen des 1-Byte-trunkierten SHA256-Prüfwerts.

  • Wenn möglich, Reduzierung des 4-Nachrichten-, 2-Runden-Handschlags auf einen 3-Nachrichten-, 1-Runden-Handschlag, wie in SSU . Dies würde eine Verschiebung von Bobs Signatur in Nachricht 4 in Nachricht 2 erfordern. Forschen Sie den Grund für die 4 Nachrichten in den zehn Jahre alten E-Mail-/Status-/Sitzungs-Archiven.

  • Minimieren des Protokoll-Overheads vor dem Padding. Obwohl Padding hinzugefügt wird und möglicherweise viel davon, bleibt das Overhead vor dem Padding immer noch Overhead. Niedrigbandbreite-Knoten müssen in der Lage sein, NTCP2 zu verwenden.

  • Beibehaltung von Zeitstempeln für Wiederholungs- und Schiefe-Erkennung.

  • Vermeiden von Problemen im Jahr 2038 in Zeitstempeln, muss bis mindestens 2106 funktionieren.

  • Erhöhung der maximalen Nachrichtengröße von 16 K auf 32 K oder 64 K.

  • Alle neuen kryptografischen Primitiven sollten leicht verfügbar sein in Bibliotheken für die Verwendung in Java (1.7), C++ und Go-Router-Implementierungen.

  • Einbeziehung von Vertretern der Java-, C++- und Go-Router-Entwickler in die Gestaltung.

  • Minimieren der Änderungen (es wird jedoch immer noch eine Menge geben).

  • Unterstützung beider Versionen in einem gemeinsamen Code (dies kann jedoch nicht möglich sein und ist in jedem Fall implementierungsabhängig).

Nicht-Ziele

  • Kugelsichere DPI-Widerstand… das wären pluggable Transports, Prop109 .

  • Ein TLS-basiertes (oder HTTPS-ähnliches) Transport-Protokoll… das wäre Prop104 .

  • Es ist okay, die symmetrische Stream-Verschlüsselung zu ändern.

  • Zeitbasierter DPI-Widerstand (Inter-Message-Zeit/Delay kann implementierungsabhängig sein; intra-Message-Delay kann an jedem Punkt eingeführt werden, einschließlich vor dem Senden des zufälligen Paddings, zum Beispiel). Künstliche Delay (was obfs4 IAT oder Inter-Arrival-Time nennt) sind unabhängig vom Protokoll selbst.

  • Abstreitbarkeit der Teilnahme an einer Sitzung (es gibt Signaturen darin).

Nicht-Ziele, die teilweise neu bewertet oder diskutiert werden können:

  • Der Grad des Schutzes vor Deep Packet Inspection (DPI)

  • Post-Quanten (PQ)-Sicherheit

  • Abstreitbarkeit

Verwandte Ziele

  • Implementierung eines NTCP 1/2-Test-Setups

Sicherheitsziele

Wir betrachten drei Parteien:

  • Alice, die eine neue Sitzung aufbauen möchte.
  • Bob, mit dem Alice eine Sitzung aufbauen möchte.
  • Mallory, der “Mann in der Mitte” zwischen Alice und Bob.

Zu jedem Zeitpunkt können höchstens zwei Teilnehmer an aktiven Angriffen teilnehmen.

Alice und Bob sind beide im Besitz eines statischen Schlüsselpaares, das in ihrer Router-Identität enthalten ist.

Das vorgeschlagene Protokoll versucht, es Alice und Bob zu ermöglichen, einen gemeinsamen geheimen Schlüssel (K) unter den folgenden Anforderungen zu vereinbaren:

  1. Private-Schlüssel-Sicherheit: Weder Bob noch Mallory erfahren etwas über Alices statischen privaten Schlüssel. Symmetrisch erfährt Alice nichts über Bobs statischen privaten Schlüssel.

  2. Der Sitzungsschlüssel K ist nur Alice und Bob bekannt.

  3. Perfekte Vorwärtsgeheimhaltung: Der vereinbarte Sitzungsschlüssel bleibt auch in Zukunft geheim, selbst wenn die statischen privaten Schlüssel von Alice und/oder Bob nach dem Schlüsselaustausch offengelegt werden.

  4. Zwei-Wege-Authentifizierung: Alice ist sich sicher, dass sie eine Sitzung mit Bob aufgebaut hat, und umgekehrt.

  5. Schutz vor Online-DPI: Stellen Sie sicher, dass es nicht trivial ist, zu erkennen, dass Alice und Bob am Protokoll teilnehmen, indem nur einfache Deep-Packet-Inspection- (DPI-) Techniken verwendet werden. Siehe unten.

  6. Begrenzte Abstreitbarkeit: Weder Alice noch Bob können ihre Teilnahme am Protokoll abstreiten, aber wenn einer von ihnen den gemeinsamen Schlüssel weitergibt, kann die andere Partei die Authentizität des Inhalts der übertragenen Daten abstreiten.

Der vorliegende Vorschlag versucht, alle fünf Anforderungen auf der Grundlage des Station-To-Station- (STS-) Protokolls zu erfüllen. Beachten Sie, dass dieses Protokoll auch die Grundlage für das SSU -Protokoll ist.

Zusätzliche DPI-Diskussion

Wir nehmen an, dass es zwei DPI-Komponenten gibt:

1) Online-DPI

Online-DPI, die alle Datenströme in Echtzeit untersuchen. Verbindungen können blockiert oder auf andere Weise manipuliert werden. Verbindungsdaten oder -metadaten können identifiziert und für die Offline-Analyse gespeichert werden. Die Online-DPI hat keinen Zugriff auf die I2P-Netzwerkdatenbank. Die Online-DPI hat nur begrenzte Echtzeit-Rechenleistung, einschließlich Längenberechnung, Feldinspektion und einfacher Berechnungen wie XOR. Die Online-DPI verfügt jedoch über die Fähigkeit, schnelle Echtzeit-Kryptofunktionen wie AES, AEAD und Hashing durchzuführen, diese wären jedoch zu teuer, um auf die meisten oder alle Datenströme angewendet zu werden. Eine Anwendung dieser Kryptofunktionen würde nur auf Datenströme angewendet, die zuvor durch die Offline-Analyse identifiziert wurden. Die Online-DPI hat nicht die Fähigkeit, ressourcenintensive Kryptofunktionen wie DH oder elligator2 durchzuführen. Die Online-DPI ist nicht speziell dafür ausgelegt, I2P zu erkennen, obwohl sie möglicherweise begrenzte Klassifizierungsregeln für diesen Zweck hat.

Es ist ein Ziel, die Protokollidentifizierung durch eine Online-DPI zu verhindern.

Der Begriff “Online-” oder “einfache” DPI wird hier als umfassend für die folgenden Angreiferfähigkeiten verstanden:

  1. Die Fähigkeit, alle gesendeten oder empfangenen Daten zu untersuchen.

  2. Die Fähigkeit, Operationen auf den beobachteten Daten durchzuführen, wie z. B. die Anwendung von Blockchiffren oder Hashfunktionen.

  3. Die Fähigkeit, Daten zu speichern und mit zuvor gesendeten Nachrichten zu vergleichen.

  4. Die Fähigkeit, Pakete zu modifizieren, zu verlangsamen oder zu fragmentieren.

Allerdings wird angenommen, dass die Online-DPI die folgenden Einschränkungen hat:

  1. Die Unfähigkeit, IP-Adressen auf Router-Hashes abzubilden. Obwohl dies mit Echtzeit-Zugriff auf die Netzwerkdatenbank trivial wäre, würde es ein DPI-System erfordern, das speziell für die Zielverfolgung von I2P entwickelt wurde.

  2. Die Unfähigkeit, Zeitinformationen zu verwenden, um das Protokoll zu erkennen.

  3. Im Allgemeinen enthält die Online-DPI-Toolbox keine Tools, die speziell für die I2P-Erkennung entwickelt wurden. Dies schließt die Erstellung von “Honigfallen” aus, die beispielsweise nicht zufälliges Padding in ihren Nachrichten enthalten würden. Beachten Sie, dass dies maschinelle Lernsysteme oder hoch konfigurierbare DPI-Tools nicht ausschließt, solange sie die anderen Anforderungen erfüllen.

Um die Payload-Analyse zu kontern, wird sichergestellt, dass alle Nachrichten nicht von zufälligen Daten zu unterscheiden sind. Dies erfordert auch, dass ihre Länge zufällig ist, was komplizierter ist als nur das Hinzufügen von zufälligem Padding. Tatsächlich argumentieren die Autoren im Anhang A, dass ein naives (d. h. uniformes) Paddingschema das Problem nicht löst. Anhang A schlägt daher vor, entweder zufällige Verzögerungen zu verwenden oder ein alternatives Paddingschema zu entwickeln, das einen vernünftigen Schutz vor dem vorgeschlagenen Angriff bieten kann.

Um den sechsten Punkt oben zu schützen, sollten Implementierungen zufällige Verzögerungen im Protokoll einbeziehen. Diese Techniken sind nicht durch diesen Vorschlag abgedeckt, könnten aber auch die Paddingslängenprobleme lösen. Zusammenfassend bietet der Vorschlag einen guten Schutz vor Payload-Analyse (wenn die Überlegungen in Anhang A berücksichtigt werden), aber nur einen begrenzten Schutz vor Flussanalyse.

2) Offline-DPI

Offline-DPI, die Daten untersuchen, die von der Online-DPI für die spätere Analyse gespeichert wurden. Die Offline-DPI kann speziell für die Erkennung von I2P entwickelt werden. Die Offline-DPI hat Echtzeit-Zugriff auf die I2P-Netzwerkdatenbank. Die Offline-DPI hat Zugriff auf diese und andere I2P-Spezifikationen. Die Offline-DPI verfügt über unbegrenzte Rechenleistung, einschließlich aller im Rahmen dieser Spezifikation definierten Kryptofunktionen.

Die Offline-DPI hat nicht die Fähigkeit, bestehende Verbindungen zu blockieren. Die Offline-DPI hat jedoch die Fähigkeit, innerhalb von Minuten nach der Einrichtung Daten an den Host/Port der Parteien zu senden, z. B. TCP RST. Die Offline-DPI hat auch die Fähigkeit, innerhalb von Minuten nach der Einrichtung (modifizierte oder unmodifizierte) vorherige Nachrichten für “Sondierungen” oder andere Gründe zu wiederholen.

Es ist kein Ziel, die Protokollidentifizierung durch eine Offline-DPI zu verhindern. Alle Decodierungen von verschleierten Daten in den ersten beiden Nachrichten, die von I2P-Routern implementiert werden, können auch von der Offline-DPI implementiert werden.

Es ist ein Ziel, versuchte Verbindungen mit Wiederholung vorheriger Nachrichten abzulehnen.

Zukunftsaufgaben

  • Untersuchen Sie das Verhalten des Protokolls, wenn Pakete von einem Angreifer fallen gelassen oder neu geordnet werden. Aktuelle interessante Arbeiten in diesem Bereich finden Sie in IACR-1150 .

  • Bieten Sie eine genauere Klassifizierung von DPI-Systemen, 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-Protokoll-Framework

Dieser Vorschlag bietet die Anforderungen auf der Grundlage des Noise-Protokoll-Frameworks NOISE (Revision 33, 2017-10-04). Noise hat ähnliche Eigenschaften wie das Station-To-Station-Protokoll, das die Grundlage für das SSU -Protokoll ist. In 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üsselableitungs-Funktion ist “Noise_XKaesobfse+hs2+hs3_25519_ChaChaPoly_SHA256” um I2P-Erweiterungen anzugeben - siehe KDF 1-Abschnitt unten) Dieses Noise-Protokoll verwendet die folgenden Primitiven:

  • Handshake-Muster: XK Alice sendet ihren Schlüssel an Bob (X) Alice kennt bereits Bobs statischen Schlüssel (K)

  • DH-Funktion: X25519 X25519-DH mit einer Schlüssellänge von 32 Bytes wie in RFC-7748 spezifiziert.

  • Verschlüsselungsfunktion: 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-Funktion: SHA256 Standard-32-Byte-Hash, der bereits umfassend in I2P verwendet wird.

Ergänzungen zum Framework

Dieser Vorschlag definiert die folgenden Erweiterungen zu Noise_XK_25519_ChaChaPoly_SHA256. Diese folgen im Allgemeinen den Richtlinien in NOISE Abschnitt 13.

  1. Klartext-ephemere Schlüssel werden mit AES-Verschlüsselung unter Verwendung eines bekannten Schlüssels und IV verschleiert. Dies ist schneller als elligator2.

  2. Zufälliges Klartext-Padding wird zu Nachrichten 1 und 2 hinzugefügt. Das Klartext-Padding wird in die Handschlag-Hash- (MixHash-) Berechnung einbezogen. Siehe die KDF-Abschnitte unten für Nachricht 2 und Nachricht 3 Teil 1. Zufälliges AEAD-Padding wird zu Nachricht 3 und Datenphasen-Nachrichten hinzugefügt.

  3. Ein zwei-Byte-Framelängenfeld wird hinzugefügt, wie für Noise über TCP erforderlich und wie in obfs4. Dies wird in den Datenphasen-Nachrichten verwendet. Nachricht 1- und 2-AEAD-Frames sind feste Länge. Nachricht 3 Teil 1 AEAD-Frame ist feste Länge. Nachricht 3 Teil 2 AEAD-Frame-Länge wird in Nachricht 1 angegeben.

  4. Das zwei-Byte-Framelängenfeld wird mit SipHash-2-4 verschleiert, wie in obfs4.

  5. Das Payload-Format wird für Nachrichten 1, 2, 3 und die Datenphase definiert. Natürlich ist dies in Noise nicht definiert.

Neue kryptografische Primitiven für I2P

Bestehende I2P-Router-Implementierungen benötigen Implementierungen für die folgenden Standard-kryptografischen Primitiven, die für die aktuellen I2P-Protokolle nicht erforderlich sind:

  1. X25519-Schlüsselgenerierung und DH

  2. AEAD_ChaCha20_Poly1305 (abgekürzt als ChaChaPoly unten)

  3. SipHash-2-4

Verarbeitungs-Overhead-Schätzung

Nachrichtengrößen für die 3 Nachrichten:

  1. 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-Größe beträgt etwa 750 Bytes. Gesamtgröße vor Padding: 814 Bytes (NTCP war 448 Bytes)
  4. nicht in NTCP2 erforderlich (NTCP war 48 Bytes)

Gesamtgröße vor Padding: NTCP2: 942 Bytes NTCP: 1088 Bytes Beachten Sie, dass wenn Alice eine Verbindung zu Bob herstellt, um eine Datenbank-Speichernachricht ihrer Router-Info zu senden, diese Nachricht nicht erforderlich ist und etwa 800 Bytes spart.

Die folgenden kryptografischen Operationen sind für jede Partei erforderlich, um den Handschlag abzuschließen und die Datenphase zu starten:

  • AES: 2
  • SHA256: 7 (Alice), 6 (Bob) (nicht einschließlich 1 Alice, 2 Bob vorab berechneter für alle Verbindungen) (nicht einschließlich HMAC-SHA256)
  • HMAC-SHA256: 19
  • ChaChaPoly: 4
  • X25519-Schlüsselgenerierung: 1
  • X25519-DH: 3
  • Signaturüberprüfung: 1 (Bob) (Alice hat ihre RI zuvor signiert, als sie generiert wurde) Vermutlich Ed25519 (abhängig vom RI-Signaturtyp)

Die folgenden kryptografischen Operationen sind für jede Partei für jede Datenphasen-Nachricht erforderlich:

  • SipHash: 1
  • ChaChaPoly: 1

Nachrichten

Alle NTCP2-Nachrichten sind kleiner oder gleich 65537 Bytes. Das Nachrichtenformat basiert auf Noise-Nachrichten mit Modifikationen für Framing und Ununterscheidbarkeit. Implementierungen, die Standard-Noise-Bibliotheken verwenden, müssen möglicherweise empfangene Nachrichten vor der Verwendung im Noise-Nachrichtenformat vorverarbeiten. Alle verschlüsselten Felder sind AEAD-Ciphertexts.

Die Einrichtungssequenz ist wie folgt:

Alice                           Bob

  SessionRequest ------------------->
  <------------------- SessionCreated
  SessionConfirmed ----------------->

Mit Noise-Terminologie ist die Einrichtungs- und Datensequenz wie folgt: (Payload-Sicherheitseigenschaften)

XK(s, rs):           Authentifizierung   Vertraulichkeit
    <- s
    ...
    -> e, es                  0                2
    <- e, ee                  2                1
    -> s, se                  2                5
    <-                        2                5

Sobald eine Sitzung eingerichtet wurde, können Alice und Bob Daten-Nachrichten austauschen.

Alle Nachrichtentypen (SessionRequest, SessionCreated, SessionConfirmed, Daten und TimeSync) werden in diesem Abschnitt spezifiziert.

Einige Notationen:

  • RH_A = Router-Hash für Alice (32 Bytes)
  • RH_B = Router-Hash für Bob (32 Bytes)

Authentifizierte Verschlüsselung

Es gibt drei separate authentifizierte Verschlüsselungs-Instanzen (CipherStates). Eine während der Handschlag-Phase und zwei (Senden und Empfangen) für die Datenphase. Jede hat ihren eigenen Schlüssel aus einer KDF.

Verschlüsselte/authentifizierte Daten werden wie folgt dargestellt

+----+----+----+----+----+----+----+----+
  |                                       |
  +                                       +
  |   Verschlüsselte und authentifizierte Daten    |
  ~               .   .   .               ~
  |                                       |
  +----+----+----+----+----+----+----+----+

ChaCha20/Poly1305

Verschlüsselte und authentifizierte Datenformat.

Eingaben für die Verschlüsselungs-/Entschlüsselungsfunktionen:

k :: 32-Byte-Verschlüsselungsschlüssel, wie aus KDF generiert

  nonce :: Zählerbasierter Nonce, 12 Bytes.
           Beginnt bei 0 und wird für jede Nachricht inkrementiert.
           Die ersten vier Bytes sind immer Null.
           Die letzten acht Bytes sind der Zähler, little-endian kodiert.
           Maximaler Wert ist 2**64 - 2.
           Die Verbindung muss getrennt und neu gestartet werden, wenn dieser Wert erreicht wird.
           Der Wert 2**64 - 1 darf nie gesendet werden.

  ad :: In der Handschlag-Phase:
        Assoziierte Daten, 32 Bytes.
        Der SHA256-Hash aller vorherigen Daten.
        In der Datenphase:
        Null-Bytes

  data :: Klartext-Daten, 0 oder mehr Bytes

Ausgabe der Verschlüsselungsfunktion, Eingabe der Entschlüsselungsfunktion:

+----+----+----+----+----+----+----+----+
|Obfs Len |                             |
+----+----+                             +
|       ChaCha20-verschlüsselte Daten         |
~               .   .   .               ~
|                                       |
+----+----+----+----+----+----+----+----+
|  Poly1305-Nachrichtenauthentifizierungscode |
+              (MAC)                    +
|             16 Bytes                  |
+----+----+----+----+----+----+----+----+

  Obfs Len :: Länge des (verschlüsselten Daten + MAC), das folgt, 16 - 65535
              Verschlüsselung mit SipHash (siehe unten)
              Nicht in Nachricht 1 oder 2 oder Nachricht 3 Teil 1 verwendet, wo die Länge fest ist
              Nicht in Nachricht 3 Teil 1 verwendet, da die Länge in Nachricht 1 angegeben ist

  verschlüsselte Daten :: Same Größe wie Klartext, 0 - 65519 Bytes

  MAC :: Poly1305-Nachrichtenauthentifizierungscode, 16 Bytes

Für ChaCha20 entspricht dies RFC-7539 , das auch ähnlich in TLS RFC-7905 verwendet wird.

Hinweise

  • Da ChaCha20 ein Stream-Chiffre ist, müssen Klartexte nicht gepaddet werden. Zusätzliche Keystream-Bytes werden verworfen.

  • Der Schlüssel für das Chiffre (256 Bits) wird durch die 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 sind bekannter Größe. Ab dem zweiten Teil von Nachricht 3 sind Frames variabler Größe. Die Nachricht 3 Teil 1-Größe wird in Nachricht 1 angegeben. Ab der Datenphase werden Frames mit einer zwei-Byte-Länge vorangestellt, die mit SipHash wie in obfs4 verschleiert ist.

  • Padding ist außerhalb des authentifizierten Daten-Frames für Nachrichten 1 und 2. Das Padding wird verwendet, um die KDF für die nächste Nachricht zu authentifizieren, so dass jede Manipulation erkannt wird. Ab Nachricht 3 ist das Padding innerhalb des authentifizierten Daten-Frames.

AEAD-Fehlerbehandlung

  • In Nachrichten 1, 2 und Nachricht 3 Teilen 1 und 2 ist die AEAD-Nachrichtengröße im Voraus bekannt. Bei einem AEAD-Authentifizierungsfehler muss der Empfänger die weitere Nachrichtenverarbeitung einstellen und die Verbindung ohne Antwort schließen. Dies sollte ein abnormaler Schließer (TCP RST) sein.

  • Für die Sondierungs-Widerstandsfähigkeit muss Bob nach einem AEAD-Fehler eine zufällige Verzögerung (Bereich TBD) einrichten und dann eine zufällige Anzahl von Bytes (Bereich TBD) lesen, bevor er die Socket schließt. Bob sollte eine Schwarze Liste von IPs mit wiederholten Fehlern aufrechterhalten.

  • In der Datenphase ist die AEAD-Nachrichtengröße “verschlüsselt” (verwischert) mit SipHash. Es muss darauf geachtet werden, dass kein Entschlüsselungs-Oracle erstellt wird. Bei einem AEAD-Authentifizierungsfehler in der Datenphase sollte der Empfänger eine zufällige Verzögerung (Bereich TBD) einrichten und dann eine zufällige Anzahl von Bytes (Bereich TBD) lesen. Nach dem Lesen oder bei Lesetimeout sollte der Empfänger eine Payload mit einem Beendigungsblock mit einem “AEAD-Fehler”-Grund senden und die Verbindung schließen.

  • Nehmen Sie die gleiche Fehleraktion für einen ungültigen Längenfeldwert in der Datenphase vor.

Schlüsselableitungs-Funktion (KDF) (für Handschlag-Nachricht 1)

Die KDF generiert einen Handschlag-Phasen-Verschlüsselungsschlüssel k aus dem DH-Ergebnis, unter Verwendung von HMAC-SHA256(Schlüssel, Daten) wie in RFC-2104 definiert. Dies sind die InitializeSymmetric(), MixHash() und MixKey()-Funktionen, genau wie in der Noise-Spezifikation definiert.

Dies ist das "e"-Nachrichtenmuster:

  // Definieren Sie den Protokollnamen.
  Setze Protokollnamen = "Noise_XKaesobfse+hs2+hs3_25519_ChaChaPoly_SHA256"
   (48 Bytes, US-ASCII-kodiert, ohne NULL-Terminierung).

  // Definieren Sie Hash h = 32 Bytes
  h = SHA256(Protokollname);

  Definieren Sie ck = 32-Byte-Verkettungsschlüssel. Kopieren Sie die h-Daten in ck.
  Setze ck = h

  Definieren Sie rs = Bobs 32-Byte-statischen Schlüssel, wie im RouterInfo veröffentlicht

  // MixHash(null Prolog)
  h = SHA256(h);

  // Bis hierhin kann alles von Alice für alle ausgehenden Verbindungen vorab berechnet werden

  // Bob-statischer Schlüssel
  // MixHash(rs)
  // || unten bedeutet Anfügen
  h = SHA256(h || rs);

  // Bis hierhin kann alles von Bob für alle eingehenden Verbindungen vorab berechnet werden

  Dies ist das "e"-Nachrichtenmuster:

  Alice generiert ein neues ephemeres Schlüsselpaar und speichert es in der e-Variablen,
  schreibt den ephemeren öffentlichen Schlüssel als Klartext in den Nachrichtenpuffer
  und hashen den öffentlichen Schlüssel zusammen mit dem alten h, um einen neuen h abzuleiten.

  // h wird als assoziierte Daten für die AEAD in Nachricht 1 verwendet
  // Bewahren Sie den Hash h für die KDF von Nachricht 2 auf

  Ende des "e"-Nachrichtenmusters.

  Dies ist das "es"-Nachrichtenmuster:

  // DH(e, rs) == DH(s, re)
  Definieren Sie input_key_material = 32-Byte-DH-Ergebnis von Alices ephemeren Schlüssel und Bobs statischem Schlüssel
  Setze input_key_material = X25519-DH-Ergebnis

  // MixKey(DH())

  Definieren Sie temp_key = 32 Bytes
  Definieren Sie HMAC-SHA256(Schlüssel, Daten) wie in [RFC-2104](https://tools.ietf.org/html/rfc2104)
  // Generieren Sie einen temp-Schlüssel aus dem Verkettungsschlüssel und dem DH-Ergebnis
  // ck ist der Verkettungsschlüssel, von der KDF für Handschlag-Nachricht 1
  temp_key = HMAC-SHA256(ck, input_key_material)
  // Überschreiben Sie das DH-Ergebnis im Speicher, nicht mehr benötigt
  input_key_material = (alle Nullen)

  // Ausgabe 1
  // Setzen Sie einen neuen Verkettungsschlüssel aus dem temp-Schlüssel
  // byte() unten bedeutet ein einzelnes Byte
  ck =       HMAC-SHA256(temp_key, byte(0x01)).

  // Ausgabe 2
  // Generieren Sie den Verschlüsselungsschlüssel k
  Definieren Sie k = 32 Bytes
  // || unten bedeutet Anfügen
  // byte() unten bedeutet ein einzelnes Byte
  k =        HMAC-SHA256(temp_key, ck || byte(0x02)).
  // Überschreiben Sie den temp-Schlüssel im Speicher, nicht mehr benötigt
  temp_key = (alle Nullen)

  // Bewahren Sie den Verkettungsschlüssel ck für die KDF von Nachricht 2 auf

  Ende des "es"-Nachrichtenmusters.

1) SessionRequest

Alice sendet an Bob.

Noise-Inhalt: Alices ephemeren Schlüssel X Noise-Payload: 16-Byte-Optionen-Block Nicht-Noise-Payload: Zufälliges Padding

(Payload-Sicherheitseigenschaften)

XK(s, rs):           Authentifizierung   Vertraulichkeit
    -> e, es                  0                2

    Authentifizierung: 0.
    Diese Payload kann von jeder Partei gesendet worden sein, einschließlich eines aktiven Angreifers.

    Vertraulichkeit: 2.
    Verschlüsselung zu einem bekannten Empfänger, Vorwärtsgeheimhaltung nur für Sender-Kompromittierung.
    Diese Payload ist verschlüsselt, basierend nur auf DHs, die den Empfänger-statischen Schlüsselpaar betreffen.
    Wenn der Empfänger-statische private Schlüssel kompromittiert wird, auch zu einem späteren Zeitpunkt, kann diese Payload entschlüsselt werden.
    Diese Nachricht kann auch wiederholt werden, da es keine ephemere Beiträge vom Empfänger gibt.

    "e": Alice generiert ein neues ephemeres Schlüsselpaar und speichert es in der e-Variablen,
         schreibt den ephemeren öffentlichen Schlüssel als Klartext in den Nachrichtenpuffer
         und hashen den öffentlichen Schlüssel zusammen mit dem alten h, um einen neuen h abzuleiten.

    "es": Ein DH wird zwischen Alices ephemeren Schlüsselpaar und Bobs statischem Schlüsselpaar durchgeführt.
          Das Ergebnis wird zusammen mit dem alten ck gehasht, um einen neuen ck und k abzuleiten, und n wird auf Null gesetzt.

Der X-Wert wird verschlüsselt, um die Payload-Unterscheidbarkeit und Einzigartigkeit zu gewährleisten, die für DPI-Gegenmaßnahmen erforderlich sind. Wir verwenden AES-Verschlüsselung, um dies zu erreichen, anstatt komplexerer und langsamerer Alternativen wie elligator2. Asymmetrische Verschlüsselung mit Bobs Router-öffentlichem Schlüssel wäre viel zu langsam. AES-Verschlüsselung verwendet Bobs Router-Hash als Schlüssel und Bobs IV, wie im Netzwerk-Verzeichnis veröffentlicht.

AES-Verschlüsselung ist nur für DPI-Widerstand erforderlich. Jede Partei, die Bobs Router-Hash und IV kennt, die im Netzwerk-Verzeichnis veröffentlicht sind, kann den X-Wert in dieser Nachricht entschlüsseln.

Das Padding wird nicht von Alice verschlüsselt. Es kann notwendig sein, dass Bob das Padding entschlüsselt, um Timing-Angriffe zu verhindern.

Rohinhalte:

+----+----+----+----+----+----+----+----+
|                                       |
+        verschleiert mit RH_B           +
|       AES-CBC-256-verschlüsselter X         |
+             (32 Bytes)                +
|                                       |
+                                       +
|                                       |
+----+----+----+----+----+----+----+----+
|   ChaChaPoly-Frame                    |
+             (32 Bytes)                +
|   k definiert in KDF für Nachricht 1      |
+   n = 0; siehe KDF für assoziierte Daten  |
+----+----+----+----+----+----+----+----+
|     unverschlüsseltes authentifiziertes         |
~         Padding (optional)            ~
|     Länge definiert in Optionen-Block   |
+----+----+----+----+----+----+----+----+

X :: 32 Bytes, AES-256-CBC-verschlüsselter X25519-ephemerer Schlüssel, little-endian
        Schlüssel: RH_B
        IV: Wie im Netzwerk-Verzeichnis von Bobs Netzwerkeintrag veröffentlicht

Padding :: Zufällige Daten, 0 oder mehr Bytes.
           Gesamtnachrichtenlänge muss 65535 Bytes oder weniger betragen.
           Gesamtnachrichtenlänge muss 287 Bytes oder weniger betragen, wenn
           Bob seine Adresse als "NTCP" veröffentlicht.
           Alice und Bob werden die Padding-Daten in der KDF für Nachricht 2 verwenden.
           Es ist authentifiziert, so dass jede Manipulation die nächste Nachricht zum Scheitern bringen wird.

Unverschlüsselte Daten (Poly1305-Authentifizierungstag nicht gezeigt):

+----+----+----+----+----+----+----+----+
|                                       |
+                                       +
|                   X                   |
+              (32 Bytes)               +
|                                       |
+                                       +
|                                       |
+----+----+----+----+----+----+----+----+
|               Optionen                 |
+              (16 Bytes)               +
|                                       |
+----+----+----+----+----+----+----+----+
|     unverschlüsseltes authentifiziertes         |
+         Padding (optional)            +
|     Länge definiert in Optionen-Block   |
~               .   .   .               ~
|                                       |
+----+----+----+----+----+----+----+----+

X :: 32 Bytes, X25519-ephemerer Schlüssel, little-endian

Optionen :: Optionen-Block, 16 Bytes, siehe unten

Padding :: Zufällige Daten, 0 oder mehr Bytes.
           Gesamtnachrichtenlänge muss 65535 Bytes oder weniger betragen.
           Gesamtnachrichtenlänge muss 287 Bytes oder weniger betragen, wenn
           Bob seine Adresse als "NTCP" veröffentlicht.
           Alice und Bob werden die Padding-Daten in der KDF für Nachricht 2 verwenden.
           Es ist authentifiziert, so dass jede Manipulation die nächste Nachricht zum Scheitern bringen wird.

Optionen-Block: Hinweis: Alle Felder sind big-endian.

+----+----+----+----+----+----+----+----+
| id | ver|  padLen | m3p2len | Rsvd(0) |
+----+----+----+----+----+----+----+----+
|        tsA        |   Reserved (0)    |
+----+----+----+----+----+----+----+----+

id :: 1 Byte, die Netzwerk-ID (derzeit 2, außer für Testnetze)
      Ab 0.9.42. Siehe Vorschlag 147.

ver :: 1 Byte, Protokollversion (derzeit 2)

padLen :: 2 Bytes, Länge des Paddings, 0 oder mehr
          Mindest-/Höchstwerte-Richtlinien TBD. Zufällige Größe von 0 bis 31 Bytes Minimum?
          (Verteilung zu bestimmen, siehe Anhang A.)

m3p2Len :: 2 Bytes, Länge des zweiten AEAD-Frames in SessionConfirmed
           (Nachricht 3 Teil 2) Siehe Hinweise unten

Rsvd :: 2 Bytes, auf 0 gesetzt für die Kompatibilität mit zukünftigen Optionen

tsA :: 4 Bytes, Unix-Timestamp, unsigned Sekunden.
       Läuft 2106 über

Reserved :: 4 Bytes, auf 0 gesetzt für die Kompatibilität mit zukünftigen Optionen

Hinweise

  • Wenn die veröffentlichte Adresse “NTCP” ist, unterstützt Bob sowohl NTCP als auch NTCP2 auf demselben Port. Für die Kompatibilität muss Alice die maximale Größe dieser Nachricht, einschließlich Padding, auf 287 Bytes oder weniger beschränken, wenn sie eine Verbindung zu einer Adresse herstellt, die als “NTCP” veröffentlicht ist. Dies erleichtert die automatische Protokollidentifizierung durch Bob. Wenn als “NTCP2” veröffentlicht, gibt es keine Größeneinschränkung. Siehe die Abschnitte “Veröffentlichte Adressen” und “Versions-Erkennung” unten.

  • Der eindeutige X-Wert im anfänglichen AES-Block stellt sicher, dass der Ciphertext für jede Sitzung unterschiedlich ist.

  • Bob muss Verbindungen ablehnen, bei denen der Timestamp-Wert zu weit von der aktuellen Zeit abweicht. Nennen wir die maximale Zeitdifferenz “D”. Bob muss einen lokalen Cache von zuvor verwendeten Handschlag-Werten aufrechterhalten und Duplikate ablehnen, um Wiederholungsangriffe zu verhindern. Die Cache-Werte sind implementierungsabhängig, jedoch kann der 32-Byte-X-Wert (oder sein verschlüsselter Äquivalent) verwendet werden.

  • Diffie-Hellman-ephemere Schlüssel dürfen niemals wiederverwendet werden, um kryptografische Angriffe zu verhindern, und die Wiederverwendung wird als Wiederholungsangriff abgelehnt.

  • Bob muss überprüfen, ob Alices ephemere Schlüssel ein gültiger Punkt auf der Kurve ist.

  • Das Padding sollte auf eine vernünftige Menge beschränkt werden. Bob kann Verbindungen ablehnen, die übermäßiges Padding aufweisen. Bob wird seine Padding-Optionen in Nachricht 2 angeben. Mindest-/Höchstwerte-Richtlinien TBD. Zufällige Größe von 0 bis 31 Bytes Minimum? (Verteilung zu bestimmen, siehe Anhang A.)

  • Bei jedem Fehler, einschließlich AEAD, DH, Timestamp, offensichtlichem Wiederholungsangriff oder Schlüsselvalidierungsfehler, muss Bob die weitere Nachrichtenverarbeitung einstellen und die Verbindung ohne Antwort schließen. Dies sollte ein abnormaler Schließer (TCP RST) sein. Für die Sondierungs-Widerstandsfähigkeit sollte Bob nach einem AEAD-Fehler eine zufällige Verzögerung (Bereich TBD) einrichten und dann eine zufällige Anzahl von Bytes (Bereich TBD) lesen, bevor er die Socket schließt.

  • DoS-Schutz: Der DH ist eine relativ teure Operation. Wie bei dem vorherigen NTCP-Protokoll sollten Router alle notwendigen Maßnahmen ergreifen, um CPU- oder Verbindungsermüdung zu verhindern. Legen Sie Grenzwerte für die maximale Anzahl aktiver Verbindungen und die maximale Anzahl von Verbindungseinrichtungen fest. Erzwingen Sie Lesezeitüberschreitungen (sowohl pro Lesevorgang als auch insgesamt für “Slowloris”). Begrenzen Sie wiederholte oder gleichzeitige Verbindungen von der gleichen Quelle. Führen Sie eine Schwarze Liste von Quellen auf, die wiederholt fehlschlagen.

  • Um eine schnelle Versions-Erkennung und Handschlag zu ermöglichen, müssen Implementierungen sicherstellen, dass Alice den gesamten Inhalt der ersten Nachricht auf einmal puffert und dann flushen muss, 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 Betriebssystem oder Middleboxes segmentiert) und von Bob auf einmal empfangen werden. Dies ist auch für die Effizienz und um die Wirksamkeit des zufälligen Paddings sicherzustellen.

  • “ver”-Feld: Das Gesamt-Noise-Protokoll, Erweiterungen und NTCP-Protokoll einschließlich Payload-Spezifikationen, die NTCP2 angeben. Dieses Feld kann verwendet werden, um die Unterstützung für zukünftige Änderungen anzugeben.

  • Nachricht 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 ihre Router-Info regelmäßig regenerieren und neu veröffentlichen, kann die Größe der aktuellen Router-Info vor dem Senden von Nachricht 3 geändert werden. Implementierungen müssen eine der beiden Strategien wählen: a) Speichern Sie die aktuelle Router-Info, um sie in Nachricht 3 zu senden, damit die Größe bekannt ist, und fügen Sie optional Raum für Padding hinzu; b) Erhöhen Sie die angegebene Größe ausreichend, um mögliche Änderungen der Router-Info-Größe zuzulassen, und fügen Sie immer Padding hinzu, wenn Nachricht 3 tatsächlich gesendet wird. In beiden Fällen muss die in Nachricht 1 angegebene “m3p2len”-Länge genau der Größe dieses Frames entsprechen, wenn er in Nachricht 3 gesendet wird.

  • Bob muss die Verbindung ablehnen, wenn nach der Validierung von Nachricht 1 und dem Lesen des Paddings noch Daten von Alice übrig bleiben. Es sollte keine zusätzlichen Daten von Alice geben, da Bob noch nicht mit Nachricht 2 geantwortet hat.

  • Das Netzwerk-ID-Feld wird verwendet, um schnell Querverbindungen zu identifizieren. Wenn dieses Feld ungleich Null ist und nicht mit Bobs Netzwerk-ID übereinstimmt, sollte Bob die Verbindung trennen und zukünftige Verbindungen blockieren. Ab 0.9.42. Siehe Vorschlag 147 für weitere Informationen.

Schlüsselableitungs-Funktion (KDF) (für Handschlag-Nachricht 2 und Nachricht 3 Teil 1)


// Nehmen Sie den in Nachricht 1 gespeicherten h
// MixHash(Ciphertext)
h = SHA256(h || 32-Byte-verschlüsselter Payload aus Nachricht 1)

// MixHash(Padding)
// Nur, wenn die Paddingslänge ungleich Null ist
h = SHA256(h || zufälliges Padding aus Nachricht 1)
// h wird als assoziierte Daten für die AEAD in Nachricht 3 Teil 1 verwendet

Dies ist das "e"-Nachrichtenmuster:

Bob generiert ein neues ephemeres Schlüsselpaar e.

// h ist von der KDF für Handschlag-Nachricht 1
// Bob-ephemerer Schlüssel Y
// MixHash(e.pubkey)
// || unten bedeutet Anfügen
h = SHA256(h || e.pubkey);

// h wird als assoziierte Daten für die AEAD in Nachricht 2 verwendet
// Bewahren Sie den Hash h für die KDF von Nachricht 3 auf

Ende des "e"-Nachrichtenmusters.

Dies ist das "ee"-Nachrichtenmuster:

// DH(e, re)
Definieren Sie input_key_material = 32-Byte-DH-Ergebnis von Alices ephemeren Schlüssel und Bobs ephemeren Schlüssel
Setze input_key_material = X25519-DH-Ergebnis
// Überschreiben Sie Alices ephemeren Schlüssel im Speicher, nicht mehr benötigt
// Alice:
e(öffentlich und privat) = (alle Nullen)
// Bob:
re = (alle Nullen)

// MixKey(DH())

Definieren Sie temp_key = 32 Bytes
Definieren Sie HMAC-SHA256(Schlüssel, Daten) wie in [RFC-2104](https://tools.ietf.org/html/rfc2104)
// Generieren Sie einen temp-Schlüssel aus dem Verkettungsschlüssel und dem DH-Ergebnis
// ck ist der Verkettungsschlüssel, von der KDF für Handschlag-Nachricht 1
temp_key = HMAC-SHA256(ck, input_key_material)
// Überschreiben Sie das DH-Ergebnis im Speicher, nicht mehr benötigt
input_key_material = (alle Nullen)

// Ausgabe 1
// Setzen Sie einen neuen Verkettungsschlüssel aus dem temp-Schlüssel
// byte() unten bedeutet ein einzelnes Byte
ck =       HMAC-SHA256(temp_key, byte(0x01)).

// Ausgabe 2
// Generieren Sie den Verschlüsselungsschlüssel k
Definieren Sie k = 32 Bytes
// || unten bedeutet Anfügen
// byte() unten bedeutet ein einzelnes Byte
k =        HMAC-SHA256(temp_key, ck || byte(0x02)).
// Überschreiben Sie den temp-Schlüssel im Speicher, nicht mehr benötigt
temp_key = (alle Nullen)

// Bewahren Sie den Verkettungsschlüssel ck für die KDF von Nachricht 3 auf

Ende des "ee"-Nachrichtenmusters.

2) SessionCreated

Bob sendet an Alice.

Noise-Inhalt: Bobs ephemeren Schlüssel Y Noise-Payload: 16-Byte-Optionen-Block Nicht-Noise-Payload: Zufälliges Padding

(Payload-Sicherheitseigenschaften)

XK(s, rs):           Authentifizierung   Vertraulichkeit
  <- e, ee                  2                1

  Authentifizierung: 2.
  Sender-Authentifizierung, resistent gegen Schlüssel-Kompromittierungs-Impersonation (KCI).
  Die Sender-Authentifizierung basiert auf einem ephemeren-statischen DH ("es" oder "se")
  zwischen dem Senders statischem Schlüsselpaar und dem Empfängers ephemeren Schlüsselpaar.
  Unter der Annahme, dass die entsprechenden privaten Schlüssel sicher sind, kann diese Authentifizierung nicht gefälscht werden.

  Vertraulichkeit: 1.
  Verschlüsselung zu einem ephemeren Empfänger.
  Diese Payload hat Vorwärtsgeheimhaltung, da die Verschlüsselung einen ephemeren-ephemeren DH ("ee") beinhaltet.
  Der Sender hat den Empfänger jedoch nicht authentifiziert,
  so dass diese Payload möglicherweise an jede Partei gesendet werden kann, einschließlich eines aktiven Angreifers.


  "e": Bob generiert ein neues ephemeres Schlüsselpaar und speichert es in der e-Variablen,
  schreibt den ephemeren öffentlichen Schlüssel als Klartext in den Nachrichtenpuffer
  und hashen den öffentlichen Schlüssel zusammen mit dem alten h, um einen neuen h abzuleiten.

  "ee": Ein DH wird zwischen Bobs ephemeren Schlüsselpaar und Alices ephemeren Schlüsselpaar durchgeführt.
  Das Ergebnis wird zusammen mit dem alten ck gehasht, um einen neuen ck und k abzuleiten, und n wird auf Null gesetzt.

Der Y-Wert wird verschlüsselt, um die Payload-Unterscheidbarkeit und Einzigartigkeit zu gewährleisten, die für DPI-Gegenmaßnahmen erforderlich sind. Wir verwenden AES-Verschlüsselung, um dies zu erreichen, anstatt komplexerer und langsamerer Alternativen wie elligator2. Asymmetrische Verschlüsselung mit Alices Router-öffentlichem Schlüssel wäre viel zu langsam. AES-Verschlüsselung verwendet Bobs Router-Hash als Schlüssel und den AES-Zustand aus Nachricht 1 (der mit Bobs IV initialisiert wurde, wie im Netzwerk-Verzeichnis veröffentlicht).

AES-Verschlüsselung ist nur für DPI-Widerstand erforderlich. Jede Partei, die Bobs Router-Hash und IV kennt, die im Netzwerk-Verzeichnis veröffentlicht sind, und die ersten 32 Bytes von Nachricht 1 abgefangen hat, kann den Y-Wert in dieser Nachricht entschlüsseln.

Rohinhalte:

+----+----+----+----+----+----+----+----+
|                                       |
+        verschleiert mit RH_B           +
|       AES-CBC-256-verschlüsselter Y         |
+              (32 Bytes)               +
|                                       |
+                                       +
|                                       |
+----+----+----+----+----+----+----+----+
|   ChaChaPoly-Frame                    |
+   Verschlüsselte und authentifizierte Daten    +
|   32 Bytes                            |
+   k definiert in KDF für Nachricht 2      +
|   n = 0; siehe KDF für assoziierte Daten  |
+                                       +
|                                       |
+----+----+----+----+----+----+----+----+
|     unverschlüsseltes authentifiziertes         |
+         Padding (optional)            +
|     Länge definiert in Optionen-Block   |
~               .   .   .               ~
|                                       |
+----+----+----+----+----+----+----+----+

Y :: 32 Bytes, AES-256-CBC-verschlüsselter X25519-ephemerer Schlüssel, little-endian
        Schlüssel: RH_B
        IV: Verwenden des AES-Zustands aus Nachricht 1

Unverschlüsselte Daten (Poly1305-Authentifizierungstag nicht gezeigt):

+----+----+----+----+----+----+----+----+
|                                       |
+                                       +
|                  Y                    |
+              (32 Bytes)               +
|                                       |
+                                       +
|                                       |
+----+----+----+----+----+----+----+----+
|               Optionen                 |
+              (16 Bytes)               +
|                                       |
+----+----+----+----+----+----+----+----+
|     unverschlüsseltes authentifiziertes         |
+         Padding (optional)            +
|     Länge definiert in Optionen-Block   |
~               .   .   .               ~
|                                       |
+----+----+----+----+----+----+----+----+

Y :: 32 Bytes, X25519-ephemerer Schlüssel, little-endian

Optionen :: Optionen-Block, 16 Bytes, siehe unten

Padding :: Zufällige Daten, 0 oder mehr Bytes.
           Gesamtnachrichtenlänge muss 65535 Bytes oder weniger betragen.
           Alice und Bob werden die Padding-Daten in der KDF für Nachricht 3 Teil 1 verwenden.
           Es ist authentifiziert, so dass jede Manipulation die nächste Nachricht zum Scheitern bringen wird.

Hinweise

  • Alice muss überprüfen, ob Bobs ephemere Schlüssel ein gültiger Punkt auf der Kurve ist.

  • Das Padding sollte auf eine vernünftige Menge beschränkt werden. Alice kann Verbindungen ablehnen, die übermäßiges Padding aufweisen. Alice wird ihre Padding-Optionen in Nachricht 3 angeben. Mindest-/Höchstwerte-Richtlinien TBD. Zufällige Größe von 0 bis 31 Bytes Minimum? (Verteilung zu bestimmen, siehe Anhang A.)

  • Bei jedem Fehler, einschließlich AEAD, DH, Timestamp, offensichtlichem Wiederholungsangriff oder Schlüsselvalidierungsfehler, muss Alice die weitere Nachrichtenverarbeitung einstellen und die Verbindung ohne Antwort schließen. Dies sollte ein abnormaler Schließer (TCP RST) sein.

  • Um einen schnellen Handschlag zu ermöglichen, müssen Implementierungen sicherstellen, dass Bob den gesamten Inhalt der ersten Nachricht auf einmal puffert und dann flushen muss, 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 Betriebssystem oder Middleboxes segmentiert) und von Alice auf einmal empfangen werden. Dies ist auch für die Effizienz und um die Wirksamkeit des zufälligen Paddings sicherzustellen.

  • Alice muss die Verbindung ablehnen, wenn nach der Validierung von Nachricht 2 und dem Lesen des Paddings noch Daten von Bob übrig bleiben. Es sollte keine zusätzlichen Daten von Bob geben, da Alice noch nicht mit Nachricht 3 geantwortet hat.

Optionen-Block: Hinweis: Alle Felder sind big-endian.


+----+----+----+----+----+----+----+----+
| Rsvd(0) | padLen  |   Reserved (0)    |
+----+----+----+----+----+----+----+----+
|        tsB        |   Reserved (0)    |
+----+----+----+----+----+----+----+----+

Reserved :: 10 Bytes insgesamt, auf 0 gesetzt für die Kompatibilität mit zukünftigen Optionen

padLen :: 2 Bytes, big-endian, Länge des Paddings, 0 oder mehr
          Mindest-/Höchstwerte-Richtlinien TBD. Zufällige Größe von 0 bis 31 Bytes Minimum?
          (Verteilung zu bestimmen, siehe Anhang A.)

tsB :: 4 Bytes, big-endian, Unix-Timestamp, unsigned Sekunden.
       Läuft 2106 über

Hinweise

  • Alice muss Verbindungen ablehnen, bei denen der Timestamp-Wert zu weit von der aktuellen Zeit abweicht. Nennen wir die maximale Zeitdifferenz “D”. Alice muss einen lokalen Cache von zuvor verwendeten Handschlag-Werten aufrechterhalten und Duplikate ablehnen, um Wiederholungsangriffe zu verhindern. Die Cache-Werte sind implementierungsabhängig, jedoch kann der 32-Byte-Y-Wert (oder sein verschlüsselter Äquivalent) verwendet werden.

Probleme

  • Sollte das Minimum- und Maximum-Padding hier hinzugefügt werden?

Verschlüsselung für Handschlag-Nachricht 3 Teil 1, unter Verwendung von Nachricht 2 KDF)


// Nehmen Sie den in Nachricht 2 gespeicherten h
// MixHash(Ciphertext)
h = SHA256(h || 24-Byte-verschlüsselter Payload aus Nachricht 2)

// MixHash(Padding)
// Nur, wenn die Paddingslänge ungleich Null ist
h = SHA256(h || zufälliges Padding aus Nachricht 2)
// h wird als assoziierte Daten für die AEAD in Nachricht 3 Teil 1 verwendet

Dies ist das "s"-Nachrichtenmuster:

Definieren Sie s = Alices statischer öffentlicher Schlüssel, 32 Bytes

// EncryptAndHash(s.publickey)
// EncryptWithAd(h, s.publickey)
// AEAD_ChaCha20_Poly1305(Schlüssel, Nonce, assoziierte Daten, Daten)
// k ist von Handschlag-Nachricht 1
// n ist 1
ciphertext = AEAD_ChaCha20_Poly1305(k, n++, h, s.publickey)
// MixHash(ciphertext)
// || unten bedeutet Anfügen
h = SHA256(h || ciphertext);

// h wird als assoziierte Daten für die AEAD in Nachricht 3 Teil 2 verwendet

Ende des "s"-Nachrichtenmusters.

Schlüsselableitungs-Funktion (KDF) (für Handschlag-Nachricht 3 Teil 2)


Dies ist das "se"-Nachrichtenmuster:

// DH(s, re) == DH(e, rs)
Definieren Sie input_key_material = 32-Byte-DH-Ergebnis von Alices statischem Schlüssel und Bobs ephemeren Schlüssel
Setze input_key_material = X25519-DH-Ergebnis
// Überschreiben Sie Bobs ephemeren Schlüssel im Speicher, nicht mehr benötigt
// Alice:
re = (alle Nullen)
// Bob:
e(öffentlich und privat) = (alle Nullen)

// MixKey(DH())

Definieren Sie temp_key = 32 Bytes
Definieren Sie HMAC-SHA256(Schlüssel, Daten) wie in [RFC-2104](https://tools.ietf.org/html/rfc2104)
// Generieren Sie einen temp-Schlüssel aus dem Verkettungsschlüssel und dem DH-Ergebnis
// ck ist der Verkettungsschlüssel, von der KDF für Handschlag-Nachricht 1
temp_key = HMAC-SHA256(ck, input_key_material)
// Überschreiben Sie das DH-Ergebnis im Speicher, nicht mehr benötigt
input_key_material = (alle Nullen)

// Ausgabe 1
// Setzen Sie einen neuen Verkettungsschlüssel aus dem temp-Schlüssel
// byte() unten bedeutet ein einzelnes Byte
ck =       HMAC-SHA256(temp_key, byte(0x01)).

// Ausgabe 2
// Generieren Sie den Verschlüsselungsschlüssel k
Definieren Sie k = 32 Bytes
// || unten bedeutet Anfügen
// byte() unten bedeutet ein einzelnes Byte
k =        HMAC-SHA256(temp_key, ck || byte(0x02)).

// h von Nachricht 3 Teil 1 wird als assoziierte Daten für die AEAD in Nachricht 3 Teil 2 verwendet

// EncryptAndHash(Payload)
// EncryptWithAd(h, Payload)
// AEAD_ChaCha20_Poly1305(Schlüssel, Nonce, assoziierte Daten, Daten)
// n ist 0
ciphertext = AEAD_ChaCha20_Poly1305(k, n++, h, Payload)
// MixHash(ciphertext)
// || unten bedeutet Anfügen
h = SHA256(h || ciphertext);

// Bewahren Sie den Verkettungsschlüssel ck für die Datenphasen-KDF auf
// Bewahren Sie den Hash h für die Datenphasen-Additional-Symmetric-Key- (SipHash-) KDF auf

Ende des "se"-Nachrichtenmusters.

// Überschreiben Sie den temp-Schlüssel im Speicher, nicht mehr benötigt
temp_key = (alle Nullen)

3) SessionConfirmed

Alice sendet an Bob.

Noise-Inhalt: Alices statischer Schlüssel Noise-Payload: Alices Router-Info und zufälliges Padding Nicht-Noise-Payload: Keine

(Payload-Sicherheitseigenschaften)

XK(s, rs):           Authentifizierung   Vertraulichkeit
  -> s, se                  2                5

  Authentifizierung: 2.
  Sender-Authentifizierung, resistent gegen Schlüssel-Kompromittierungs-Impersonation (KCI). Die
  Sender-Authentifizierung basiert auf einem ephemeren-statischen DH ("es" oder "se")
  zwischen dem Senders statischem Schlüsselpaar und dem Empfängers ephemeren Schlüsselpaar.
  Unter der Annahme, dass die entsprechenden privaten Schlüssel sicher sind, kann diese Authentifizierung nicht gefälscht werden.

  Vertraulichkeit: 5.
  Verschlüsselung zu einem bekannten Empfänger, starke Vorwärtsgeheimhaltung.
  Diese Payload ist verschlüsselt, basierend auf einem ephemeren-ephemeren DH sowie einem ephemeren-statischen DH mit dem Empfängers statischem Schlüsselpaar.
  Unter der Annahme, dass die ephemeren privaten Schlüssel sicher sind und der Empfänger nicht aktiv von einem Angreifer, der seinen statischen privaten Schlüssel gestohlen hat, nachgeahmt wird, kann diese Payload nicht entschlüsselt werden.

  "s": Alice schreibt ihren statischen öffentlichen Schlüssel aus der s-Variablen in den Nachrichtenpuffer,
  verschlüsselt ihn und hashen die Ausgabe zusammen mit dem alten h, um einen neuen h abzuleiten.

  "se": Ein DH wird zwischen Alices statischem Schlüsselpaar und Bobs ephemeren Schlüsselpaar durchgeführt.
  Das Ergebnis wird zusammen mit dem alten ck gehasht, um einen neuen ck und k abzuleiten, und n wird auf Null gesetzt.

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 Router-Info, optionale Optionen und optionales Padding. Sie verwenden unterschiedliche Schlüssel, da die MixKey()-Funktion zwischen ihnen aufgerufen wird.

Rohinhalte:

+----+----+----+----+----+----+----+----+
|                                       |
+   ChaChaPoly-Frame (48 Bytes)         +
|   Verschlüsselte und authentifizierte         |
+   Alice-statischer Schlüssel S                  +
|      (32 Bytes)                       |
+                                       +
|     k definiert in KDF für Nachricht 2    |
+     n = 1                             +
|     siehe KDF für assoziierte Daten       |
+                                       +
|                                       |
+----+----+----+----+----+----+----+----+
|                                       |
+     Länge angegeben in Nachricht 1     +
|                                       |
+   ChaChaPoly-Frame                    +
|   Verschlüsselte und authentifizierte         +
+                                       +
|       Alice-Router-Info                |
+       unter Verwendung des Blockformats 2            +
|       Alice-Optionen (optional)        |
+       unter Verwendung des Blockformats 1            +
|       Arbiträres Padding               |
+       unter Verwendung des Blockformats 254          +
|                                       |
+                                       +
| k definiert in KDF für Nachricht 3 Teil 2 |
+     n = 0                             +
|     siehe KDF für assoziierte Daten       |
~               .   .   .               ~
|                                       |
+----+----+----+----+----+----+----+----+

S :: 32 Bytes, ChaChaPoly-verschlüsselter Alices X25519-statischer Schlüssel, little-endian
     innerhalb von 48-Byte-ChaChaPoly-Frame

Unverschlüsselte Daten (Poly1305-Authentifizierungstags nicht gezeigt):

+----+----+----+----+----