注意: この記事はLLMによって英語から翻訳されたものです。正確性については保証いたしかねますので、あらかじめご了承ください。英語の原文はこちら。
Invisible Internet Project (I2P) は、匿名での接続を可能にする暗号化されたプライベートネットワークレイヤーです。Tor(詳しくない方はこちらの記事をご覧ください)とは異なり、I2Pはインターネットへのアクセスを目的としたものではなく(outproxyを使えば可能ですが)、匿名ウェブサイト(I2P site、またはeepSite)、トレント、IRCなど、ネットワーク内のさまざまなサービスにアクセスするために設計されています。I2Pは2003年にリリースされ、現在バージョン1.5となっています。
I2Pの実装の一部はTorと似ている部分があります(オニオン暗号化の概念)が、いくつかの追加的な特徴も持っています(主にgarlic routingとgarlic encryption)。公式ドキュメントは少し理解しにくいため、この記事ではシステムの各部分がどのように機能しているかについて、わかりやすく概要を説明することを目指します。
I2Pの仕組み#
概要とトンネル#
最初に知っておくべき用語は「ルーター」です。基本的に、I2Pを実行しているすべてのクライアントを指します。各ルーターには、データの受信と送信を行うデータパイプラインであるインバウンドトンネルとアウトバウンドトンネルがあります。受信データと送信データは、匿名性とパフォーマンスの向上のために分離されています。
以下の図1は、異なるユーザー間でどのようにデータ交換が行われるかを示しています。これはいくつかのトンネルを省略した簡略版であることに注意してください。

AliceとBobが通信していることがわかります。Bobに送信されるデータはAliceのアウトバウンドトンネルを経由し、次にCharlieのインバウンドトンネルへと流れます。一方、Bobから受信するデータはBobのアウトバウンドトンネルを経由し、次にAliceのインバウンドトンネルへと流れます。
トンネルと暗号化の詳細#
前のセクションを読んで、システムの動作についての概要は把握できましたが、クライアントのデータがどのように秘密に保たれるかについてはまだ説明していません。このセクションではそれについて説明します。
答えの主要な部分はトンネルにあります。Torと同様に、通信する2つのクライアントの間には複数のルーター(ホップ)が存在します。通常は2つまたは3つ(図2のように)ですが、最大7つ、最小0に設定することも可能です。

図2は、AliceがBobにメッセージを送信した場合に何が起こるかを示しています。やり取りを説明する前に、いくつかの用語を定義する必要があります:
aはOutbound Gatewayです。技術的には、これはAliceのルーターですbとcはOutbound Tunnel Participantです。1つまたは複数存在でき、メッセージを次のノードに転送する役割を担いますdはOutbound Endpointです。これは(Aliceに属する)アウトバウンドトンネルの終端であり、(Bobに属する)インバウンドトンネルにメッセージを送信する役割を担いますeはInbound Gatewayです。クライアントが他のユーザーからの連絡を受け付けたい場合、Inbound Gatewayのアドレスがネットワークデータベースに公開されます(詳細は後述)fとgはInbound Tunnel Participantです。bやcと同じ役割を持ちます。トンネル参加者は自分がインバウンドトンネルとアウトバウンドトンネルのどちらに属しているかを知ることはなく、メッセージの受信と次のホップへの送信のみを行いますhはInbound Endpointです。技術的には、Bobのルーターです
メッセージを送信する際、暗号化レベルでは以下のことが行われます:
aはメッセージをより小さな1,024バイトのメッセージに分割します。パイプラインに流れるすべてのメッセージは、さまざまな攻撃を防ぐために固定サイズになっていますaはすべての1,024バイトメッセージをh向けに暗号化し、AliceとBobだけがその内容を知ることができるようにしますaは(1)で得られた結果をd向けに暗号化し、次にその結果をc向けに暗号化し、さらにその結果をb向けに暗号化します(参加者の数だけこれを繰り返します)。これはTorのオニオン暗号化と同様の手法ですbはトンネルメッセージを受信し、復号化してcに転送しますcはトンネルメッセージを受信し、復号化してdに転送しますdは1,024バイトメッセージを受信し、ステップ(1)で分割された元のデータを復元するために再構成し、Inbound Gatewayeに送信しますeはメッセージを受信し、1,024バイトのトンネルメッセージに分割して、それぞれをfに送信しますfはトンネルメッセージを受信し、暗号化してgに転送しますgはトンネルメッセージを受信し、暗号化してhに転送しますhはgによって暗号化されたメッセージを復号化し、fによって暗号化された結果を復号化し、eによって暗号化された結果を復号化し、aによって暗号化された結果を復号化します。そしてすべてを組み立てて、ステップ(1)にあった元の平文メッセージを復元します
なお、a はメッセージの暗号化に decrypt 関数を使用し、b と c はその復号化に encrypt 関数を使用します。f と g も encrypt 関数を使用する(今度はメッセージの暗号化のため)ため、参加者は自分がインバウンドトンネルとアウトバウンドトンネルのどちらに属しているか判別できません。また、トンネルメッセージが常に1,024バイトになるよう、各プロセスはパディングを使用することがあります。
トンネルの確立とデータベース#
ここまで読んでいただいた方は、I2Pの仕組み、データの機密性の保持方法、トンネルの役割について大まかな理解ができたと思います。ただし、まだ説明していないことが2つあります。トンネルがどのように作成されるか、そしてクライアントがどのように匿名性を保つかです(Torに詳しい方は、2つ目の疑問についてはすでに理解できているかもしれません)。
データベース#
システムにおいて重要なのは、ルートを作成するために他のルーターに接続する能力と、サービスへのアクセス方法を知ることです。Torではノードの情報を問い合わせることができる中央ポイントがあります。I2Pにもルーター情報を取得するための中央ポイントがありますが、これは網羅的なデータベースではありません。代わりに、クライアントがネットワークマップを初期構築できるよう、いくつかのルーターアドレスを提供するだけです。ルーターデータベース自体はnetDbと呼ばれる分散データベースです。netDbは「floodfill」と呼ばれる技術で分散されており、それに参加する各ルーターは「floodfill router」と呼ばれます。データベースにはRouterInfoとLeaseSetの2つのエンティティが含まれています。
ネットワークに参加している各ルーターにはRouterInfoというデータベースエントリがあります。これには以下の情報が含まれています:
- ルーターのアイデンティティ(暗号化キー、署名キー、および証明書)
- ルーターに到達するための連絡先アドレス
- 公開された日時
- ルーターの機能などを共有するためのさまざまなテキストオプション
- 署名キーを使用してルーターが作成した上記すべてのフィールドの署名
クライアントにメッセージを送信できるようにするため、各インバウンドトンネルにはデータベース内にLeaseSetがあります。以下の情報が提供されます:
- トンネルゲートウェイルーター(RouterInfoエンティティで定義されているもの)
- トンネルID(4バイトの数値)
- トンネルの有効期限(デフォルトでは10分ごと)
- 宛先の暗号化キー、署名キー、および証明書
- LeaseSetデータの署名
なお、LeaseSetは公開されない場合もあります(例えば、クライアントがIRCを使用している場合)。その場合、I2PはLeaseSet情報を関連する当事者にのみ共有します。
特に注目すべきLeaseSetの種類が1つあります:暗号化されたLeaseSetです。その名の通り、正しいキーを持つクライアントのみがLeaseSet情報を取得でき、したがってインバウンドトンネルに接続することが可能になります。なお、ルーターがLeaseSetをデータベースに記録する際は、匿名性を保つためにアウトバウンドトンネルを使用して行います。
トンネルの確立#
ルーターがトンネルを作成したい場合、データベースのRouteInfoエントリからルーターを見つけ、さまざまなヒューリスティックを用いて最適なルートを選択します。その後、ルーターに連絡してトンネルの設定許可を求める必要があります。
潜在的なトンネルメンバーにはそれぞれ、通過するデータの暗号化に使用するトンネルIDと暗号化キーが提供され、ビルドリクエストへの応答にも使用されます。さらに:
- 中間トンネル参加者とインバウンドゲートウェイには、次のホップの情報(ルーターアドレスとトンネルID)が提供されます
- アウトバウンドエンドポイントには、情報を送信したいインバウンドゲートウェイの情報が提供されます
すべての参加者がトンネルへの参加に同意すると、開始ルーターはデータの送受信にそのトンネルを使用できるようになります。参加者は複数のトンネルを開くことができるため、最初に提供されたトンネルIDにより、受信したパケットがどのトンネルに属しているか、したがってそのメッセージの次のホップがどこかを知ることができます。ルーターはメッセージの前のホップと次のホップしか見ることができないため、誰がメッセージを送信しているか、どこに向かっているかを知ることはできず、匿名性が確保されます。
参考文献と追加資料#
- https://geti2p.net/en/docs/how/intro
- https://geti2p.net/en/docs/how/tunnel-routing
- https://geti2p.net/spec/tunnel-creation
- https://geti2p.net/en/docs/tunnels/implementation
- https://geti2p.net/en/comparison/tor
- https://geti2p.net/en/docs/how/garlic-routing
- https://geti2p.net/en/docs/how/network-database
- Effects of Shared Bandwidth on Anonymity of the I2P Network Users
- https://geti2p.net/ja/docs/how/tech-intro
- Privacy-Implications of Performance-Based Peer Selection by Onion-Routers: A Real-World Case Study using I2P
- https://geti2p.net/en/docs/how/threat-model
- https://geti2p.net/en/blog/post/2021/09/07/Level-Up-Encrypted-Leasesets