Überblick
HINWEIS: VERALTET - Dies ist die ElGamal tunnel build Spezifikation. Siehe tunnel-creation-ecies für die X25519 tunnel build Spezifikation.
Dieses Dokument spezifiziert die Details der verschlüsselten tunnel Build-Nachrichten, die verwendet werden, um tunnel mit einer “nicht-interaktiven Teleskopierung”-Methode zu erstellen. Siehe das tunnel Build-Dokument TUNNEL-IMPL für einen Überblick über den Prozess, einschließlich Peer-Auswahl und Sortierungsmethoden.
Die Tunnel-Erstellung wird durch eine einzelne Nachricht bewerkstelligt, die entlang des Pfades der Peers im Tunnel weitergegeben, an Ort und Stelle umgeschrieben und zurück an den Tunnel-Ersteller übertragen wird. Diese einzelne Tunnel-Nachricht besteht aus einer variablen Anzahl von Datensätzen (bis zu 8) - einen für jeden potentiellen Peer im Tunnel. Einzelne Datensätze werden asymmetrisch (ElGamal CRYPTO-ELG ) verschlüsselt, um nur von einem bestimmten Peer entlang des Pfades gelesen werden zu können, während eine zusätzliche symmetrische Verschlüsselungsschicht (AES CRYPTO-AES ) bei jedem Hop hinzugefügt wird, um den asymmetrisch verschlüsselten Datensatz nur zum angemessenen Zeitpunkt freizulegen.
Anzahl der Datensätze
Nicht alle Datensätze müssen gültige Daten enthalten. Die Build-Nachricht für einen 3-Hop-Tunnel kann beispielsweise mehr Datensätze enthalten, um die tatsächliche Länge des Tunnels vor den Teilnehmern zu verbergen. Es gibt zwei Build-Nachrichtentypen. Die ursprüngliche Tunnel Build Message (TBM ) enthält 8 Datensätze, was für jede praktische Tunnellänge mehr als ausreichend ist. Die neuere Variable Tunnel Build Message (VTBM ) enthält 1 bis 8 Datensätze. Der Urheber kann zwischen der Größe der Nachricht und dem gewünschten Grad der Tunnellängen-Verschleierung abwägen.
Im aktuellen Netzwerk sind die meisten tunnel 2 oder 3 Hops lang. Die aktuelle Implementierung verwendet eine 5-Datensatz-VTBM zum Aufbau von tunneln mit 4 Hops oder weniger und die 8-Datensatz-TBM für längere tunnel. Die 5-Datensatz-VTBM (die bei Fragmentierung in drei 1KB tunnel-Nachrichten passt) reduziert den Netzwerkverkehr und erhöht die Erfolgsrate beim Aufbau, da kleinere Nachrichten weniger wahrscheinlich verworfen werden.
Die Antwortnachricht muss den gleichen Typ und die gleiche Länge wie die Build-Nachricht haben.
Spezifikation der Anfrage-Datensätze
Auch spezifiziert in der I2NP-Spezifikation BRR .
Klartext des Datensatzes, nur für den angefragten Hop sichtbar:
| Bytes | Contents |
|---|---|
| 0-3 | tunnel ID to receive messages as, nonzero |
| 4-35 | local router identity hash |
| 36-39 | next tunnel ID, nonzero |
| 40-71 | next router identity hash |
| 72-103 | AES-256 tunnel layer key |
| 104-135 | AES-256 tunnel IV key |
| 136-167 | AES-256 reply key |
| 168-183 | AES-256 reply IV |
| 184 | flags |
| 185-188 | request time (in hours since the epoch, rounded down) |
| 189-192 | next message ID |
| 193-221 | uninterpreted / random padding |
Der tunnel layer key, tunnel IV key, reply key und reply IV sind jeweils zufällige 32-Byte-Werte, die vom Ersteller generiert werden und nur für diesen Build-Request-Datensatz verwendet werden.
Das Flags-Feld enthält folgendes (Bit-Reihenfolge: 76543210, Bit 7 ist MSB):
| Bit | Description |
|---|---|
| 7 | if set, allow messages from anyone |
| 6 | if set, allow messages to anyone, and send the reply to the specified next hop in a Tunnel Build Reply Message |
| 5-0 | Undefined, must set to 0 for compatibility with future options |
Erstellung von Anfragedatensätzen
Jeder Hop erhält eine zufällige Tunnel-ID, die nicht null ist. Die aktuellen und nächsten Hop-Tunnel-IDs werden ausgefüllt. Jeder Datensatz erhält einen zufälligen Tunnel-IV-Schlüssel, Antwort-IV, Ebenen-Schlüssel und Antwort-Schlüssel.
Request Record Verschlüsselung
Dieser Klartextdatensatz wird mit ElGamal 2048 CRYPTO-ELG verschlüsselt unter Verwendung des öffentlichen Verschlüsselungsschlüssels des Hops und in einen 528 Byte Datensatz formatiert:
| Bytes | Contents |
|---|---|
| 0-15 | First 16 bytes of the SHA-256 of the current hop's router identity |
| 16-527 | ElGamal-2048 encrypted request record |
Da der Klartext das gesamte Feld verwendet, ist keine zusätzliche Auffüllung über SHA256(cleartext) + cleartext hinaus erforderlich.
Jeder 528-Byte-Datensatz wird dann iterativ verschlüsselt (unter Verwendung von AES-Entschlüsselung mit dem Antwortschlüssel und der Antwort-IV für jeden Hop), sodass die router-Identität nur für den jeweiligen Hop im Klartext vorliegt.
Hop-Verarbeitung und Verschlüsselung
Wenn ein Hop eine TunnelBuildMessage empfängt, durchsucht er die darin enthaltenen Datensätze nach einem, der mit seinem eigenen identity hash (auf 16 Bytes gekürzt) beginnt. Anschließend entschlüsselt er den ElGamal-Block aus diesem Datensatz und ruft den geschützten Klartext ab. An diesem Punkt stellt er sicher, dass die tunnel-Anfrage kein Duplikat ist, indem er den AES-256-Antwortschlüssel in einen Bloom-Filter einspeist. Duplikate oder ungültige Anfragen werden verworfen. Datensätze, die nicht mit der aktuellen Stunde oder der vorherigen Stunde (falls kurz nach dem Stundenbeginn) gestempelt sind, müssen verworfen werden. Zum Beispiel: Nimm die Stunde aus dem Zeitstempel, wandle sie in eine vollständige Zeit um, und wenn sie mehr als 65 Minuten zurück oder 5 Minuten voraus liegt, ist sie ungültig. Der Bloom-Filter muss eine Dauer von mindestens einer Stunde (plus einige Minuten, um Uhrenabweichungen zu berücksichtigen) haben, damit doppelte Datensätze in der aktuellen Stunde, die nicht durch Überprüfung des Stunden-Zeitstempels im Datensatz abgelehnt werden, vom Filter abgelehnt werden.
Nachdem sie entschieden haben, ob sie der Teilnahme am tunnel zustimmen oder nicht, ersetzen sie den Datensatz, der die Anfrage enthalten hatte, durch einen verschlüsselten Antwortblock. Alle anderen Datensätze werden mit AES-256 CRYPTO-AES unter Verwendung des mitgelieferten Antwortschlüssels und IV verschlüsselt. Jeder wird separat mit AES/CBC unter Verwendung desselben Antwortschlüssels und Antwort-IV verschlüsselt. Der CBC-Modus wird nicht über Datensätze hinweg fortgesetzt (verkettet).
Jeder Hop kennt nur seine eigene Antwort. Wenn er zustimmt, wird er den tunnel bis zum Ablauf aufrechterhalten, auch wenn er nicht genutzt wird, da er nicht wissen kann, ob alle anderen Hops zugestimmt haben.
Reply Record Spezifikation
Nachdem der aktuelle Hop seinen Datensatz gelesen hat, ersetzt er ihn durch einen Antwortdatensatz, der angibt, ob er der Teilnahme am tunnel zustimmt oder nicht, und falls nicht, klassifiziert er seinen Ablehnungsgrund. Dies ist einfach ein 1-Byte-Wert, wobei 0x0 bedeutet, dass er der Teilnahme am tunnel zustimmt, und höhere Werte höhere Ablehnungsgrade bedeuten.
Die folgenden Ablehnungscodes sind definiert:
- TUNNEL_REJECT_PROBABALISTIC_REJECT = 10
- TUNNEL_REJECT_TRANSIENT_OVERLOAD = 20
- TUNNEL_REJECT_BANDWIDTH = 30
- TUNNEL_REJECT_CRIT = 50
Um andere Ursachen, wie das Herunterfahren des routers, vor Peers zu verbergen, verwendet die aktuelle Implementierung TUNNEL_REJECT_BANDWIDTH für fast alle Ablehnungen.
Die Antwort wird mit dem AES-Sitzungsschlüssel verschlüsselt, der im verschlüsselten Block übertragen wurde, und mit 495 Bytes an Zufallsdaten aufgefüllt, um die vollständige Datensatzgröße zu erreichen. Die Auffüllung wird vor dem Statusbyte platziert:
AES-256-CBC(SHA-256(padding+status) + padding + status, key, IV)
| Bytes | Contents |
|---|---|
| 0-31 | SHA-256 of bytes 32-527 |
| 32-526 | Random padding |
| 527 | Reply value |
Tunnel Build Message Vorbereitung
Beim Erstellen einer neuen Tunnel Build Message müssen zunächst alle Build Request Records erstellt und asymmetrisch mit ElGamal CRYPTO-ELG verschlüsselt werden. Jeder Record wird dann präventiv mit den Antwortschlüsseln und IVs der früheren Hops im Pfad entschlüsselt, wobei AES CRYPTO-AES verwendet wird. Diese Entschlüsselung sollte in umgekehrter Reihenfolge durchgeführt werden, damit die asymmetrisch verschlüsselten Daten beim richtigen Hop im Klartext erscheinen, nachdem ihr Vorgänger sie verschlüsselt hat.
Die überschüssigen Datensätze, die für einzelne Anfragen nicht benötigt werden, werden vom Ersteller einfach mit zufälligen Daten gefüllt.
Tunnel Build Message Delivery
Für ausgehende Tunnel erfolgt die Zustellung direkt vom tunnel-Ersteller zum ersten Hop, wobei die TunnelBuildMessage so verpackt wird, als wäre der Ersteller nur ein weiterer Hop im tunnel. Für eingehende Tunnel erfolgt die Zustellung über einen bestehenden ausgehenden tunnel. Der ausgehende tunnel stammt im Allgemeinen aus demselben Pool wie der neue tunnel, der aufgebaut wird. Wenn kein ausgehender tunnel in diesem Pool verfügbar ist, wird ein ausgehender Erkundungs-tunnel verwendet. Beim Start, wenn noch kein ausgehender Erkundungs-tunnel existiert, wird ein gefälschter 0-Hop ausgehender tunnel verwendet.
Tunnel Build Message Endpoint-Behandlung
Bei der Erstellung eines outbound tunnel wird, wenn die Anfrage einen outbound endpoint erreicht (wie durch das ‘allow messages to anyone’ Flag bestimmt), der Hop wie üblich verarbeitet, wobei eine Antwort anstelle des Datensatzes verschlüsselt und alle anderen Datensätze verschlüsselt werden. Da es jedoch keinen ’next hop’ gibt, an den die TunnelBuildMessage weitergeleitet werden könnte, werden stattdessen die verschlüsselten Antwortdatensätze in eine TunnelBuildReplyMessage (TBRM ) oder VariableTunnelBuildReplyMessage (VTBRM ) eingesetzt (der Nachrichtentyp und die Anzahl der Datensätze müssen mit denen der Anfrage übereinstimmen) und an den in der Anfrage angegebenen reply tunnel übermittelt. Dieser reply tunnel leitet die Tunnel Build Reply Message zurück an den tunnel-Ersteller weiter, genau wie bei jeder anderen Nachricht TUNNEL-OP . Der tunnel-Ersteller verarbeitet sie dann wie unten beschrieben.
Der Reply-Tunnel wurde vom Ersteller wie folgt ausgewählt: Im Allgemeinen ist es ein eingehender Tunnel aus demselben Pool wie der neue ausgehende Tunnel, der erstellt wird. Wenn kein eingehender Tunnel in diesem Pool verfügbar ist, wird ein eingehender Exploratory-Tunnel verwendet. Beim Start, wenn noch kein eingehender Exploratory-Tunnel existiert, wird ein gefälschter 0-Hop eingehender Tunnel verwendet.
Für die Erstellung eines inbound tunnel erreicht die Anfrage den inbound endpoint (auch bekannt als tunnel creator), es ist nicht erforderlich, eine explizite Tunnel Build Reply Message zu generieren, und der router verarbeitet jede der Antworten wie folgt.
Tunnel Build Reply Nachrichtenverarbeitung
Um die Antwortdatensätze zu verarbeiten, muss der Ersteller einfach jeden Datensatz einzeln mit AES entschlüsseln, wobei er den Antwortschlüssel und IV jedes Hops im tunnel nach dem Peer verwendet (in umgekehrter Reihenfolge). Dies legt dann die Antwort frei, die angibt, ob sie der Teilnahme am tunnel zustimmen oder warum sie ablehnen. Wenn alle zustimmen, gilt der tunnel als erstellt und kann sofort verwendet werden, aber wenn jemand ablehnt, wird der tunnel verworfen.
Die Zustimmungen und Ablehnungen werden im Profil jedes Peers PEER-SELECTION vermerkt, um bei zukünftigen Bewertungen der Peer-Tunnel-Kapazität verwendet zu werden.
Geschichte und Hinweise
Diese Strategie entstand während einer Diskussion in der I2P-Mailingliste zwischen Michael Rogers, Matthew Toseland (toad) und jrandom bezüglich des Predecessor-Angriffs. Siehe TUNBUILD-SUMMARY , TUNBUILD-REASONING . Sie wurde in Release 0.6.1.10 am 2006-02-16 eingeführt, was das letzte Mal war, dass eine nicht-rückwärtskompatible Änderung in I2P vorgenommen wurde.
Hinweise:
- Dieses Design verhindert nicht, dass zwei feindliche Peers innerhalb eines tunnels ein oder mehrere Anfrage- oder Antwort-Datensätze markieren, um zu erkennen, dass sie sich im selben tunnel befinden, aber dies kann vom tunnel-Ersteller beim Lesen der Antwort erkannt werden, wodurch der tunnel als ungültig markiert wird.
- Dieses Design beinhaltet keinen Arbeitsnachweis für den asymmetrisch verschlüsselten Abschnitt, obwohl der 16-Byte-Identitäts-Hash halbiert werden könnte, wobei die Hälfte durch eine Hashcash-Funktion mit Kosten von bis zu 2^64 ersetzt wird.
- Dieses Design allein verhindert nicht, dass zwei feindliche Peers innerhalb eines tunnels Timing-Informationen verwenden, um zu bestimmen, ob sie sich im selben tunnel befinden. Die Verwendung von stapelweiser und synchronisierter Anfrage-Zustellung könnte helfen (Anfragen sammeln und sie zur (ntp-synchronisierten) Minute versenden). Dies ermöglicht es Peers jedoch, die Anfragen zu ‘markieren’, indem sie diese verzögern und die Verzögerung später im tunnel erkennen, obwohl möglicherweise das Verwerfen von Anfragen, die nicht in einem kleinen Zeitfenster zugestellt werden, funktionieren würde (obwohl dies einen hohen Grad an Uhren-Synchronisation erfordern würde). Alternativ könnten einzelne Hops eine zufällige Verzögerung einfügen, bevor sie die Anfrage weiterleiten?
- Gibt es nicht-fatale Methoden zum Markieren der Anfrage?
- Der Zeitstempel mit einer einstündigen Auflösung wird zur Replay-Verhinderung verwendet. Die Einschränkung wurde erst ab Version 0.9.16 durchgesetzt.
Zukünftige Arbeiten
- In der aktuellen Implementierung lässt der Originator einen Datensatz für sich selbst leer. Daher kann eine Nachricht mit n Datensätzen nur einen tunnel mit n-1 Hops aufbauen. Dies scheint für Inbound-tunnels notwendig zu sein (wo der vorletzte Hop das Hash-Präfix für den nächsten Hop sehen kann), aber nicht für Outbound-tunnels. Dies ist zu untersuchen und zu verifizieren. Falls es möglich ist, den verbleibenden Datensatz zu verwenden, ohne die Anonymität zu gefährden, sollten wir dies tun.
- Weitere Analyse möglicher Tagging- und Timing-Angriffe, die in den obigen Hinweisen beschrieben sind.
- Nur VTBM verwenden; keine alten Peers auswählen, die es nicht unterstützen.
- Der Build Request Record spezifiziert keine tunnel-Lebensdauer oder Ablaufzeit; jeder Hop lässt den tunnel nach 10 Minuten ablaufen, was eine netzwerkweite fest codierte Konstante ist. Wir könnten ein Bit im Flag-Feld verwenden und 4 (oder 8) Bytes aus dem Padding nehmen, um eine Lebensdauer oder Ablaufzeit zu spezifizieren. Der Anforderer würde diese Option nur spezifizieren, wenn alle Teilnehmer sie unterstützen würden.
Referenzen
- BRR - BuildRequestRecord Spezifikation
- CRYPTO-AES - AES-Verschlüsselung
- CRYPTO-ELG - ElGamal-Verschlüsselung
- HASHING-IT-OUT
- PEER-SELECTION
- PREDECESSOR
- PREDECESSOR-2008
- TBM - TunnelBuildMessage
- TBRM - TunnelBuildReplyMessage
- TUNBUILD-REASONING
- TUNBUILD-SUMMARY
- TUNNEL-IMPL
- TUNNEL-OP
- VTBM - VariableTunnelBuildMessage
- VTBRM - VariableTunnelBuildReplyMessage