P2Pファイル転送
概要
HyperDrive の「合言葉共有」機能が WebRTC DataChannel を使って ブラウザ間で直接ファイルを転送する仕組みを説明する。
「サーバーを介さない」の正確な意味
ファイルの**実体(バイナリデータ)**は HyperDrive サーバーを通過しない。 一方、誰が誰に何を送ろうとしているかを示すメタデータや接続確立のための シグナリング情報はサーバー経由となる。後述の表を参照。
通信フロー全体図
[送信者ブラウザ] ←(1)WS→ [HyperDrive サーバー] ←(1)WS→ [受信者ブラウザ]
↕ ↕
(2)STUN (Valkey)
↕
[送信者ブラウザ] ←────────(3) WebRTC DataChannel ────────→ [受信者ブラウザ]
(ファイルデータはここを通る)
各番号について:
- WebSocket シグナリング(SDP offer/answer・ICE candidates)— サーバー経由
- STUN による外部IP確認(異なるネットワーク間でのP2P確立に必要)
- WebRTC DataChannel によるファイル直接転送 — サーバー不経由
サーバーを経由するものとしないもの
NATトラバーサルとTURNリレー
HyperDrive は同一LAN内だけでなく、インターネット越しの異なるネットワーク間での 使用も想定している。この場合、NATトラバーサルが必要になる。
NATトラバーサルの流れ:
- 双方が STUN サーバーに問い合わせ、自分の外部IPアドレスとポートを取得
- ICE候補としてシグナリングサーバー経由で相手に通知
- 直接P2P接続を試みる(多くのNAT環境では成功)
TURN リレーが必要になるケース:
- 送受信者の一方または双方が Symmetric NAT 配下にある場合
- 直接P2P が確立できない場合、TURN サーバーがファイルデータをリレーする
- TURNを経由してもDTLS暗号化は維持されるが、TURNサーバー管理者は 暗号化されたパケットを通過させる(内容は読めない)
自己ホスト構成での注意:
- TURN サーバーも自己管理になるため、第三者サービスへのデータ通過は発生しない
- 同一LAN内での使用であれば STUN/TURN ともに不要
セキュアなファイル共有と言えるか
「セキュアか」の問いに対して、以下の軸で正直に評価する。
✅ セキュアと言える点
ファイル実体の非通過性
- ファイルのバイナリデータはHyperDriveサーバーに送信・保存されない
- サーバーにファイル内容のログが残らない
- 機密文書の転送時にサーバー管理者がアクセスできない
DTLS暗号化(WebRTC DataChannel)
- WebRTC DataChannel は DTLS(Datagram Transport Layer Security)で必ず暗号化される
- DTLS は TLS と同等の暗号強度(TLS 1.2/1.3 相当)
- 通信経路での盗聴が困難
ファイル整合性検証
- 送受信前後でファイルハッシュ(filehash)を比較し、改ざん・破損を検出できる
⚠️ 留意すべき点
シグナリング時のメタデータ露出
- ファイル名・サイズ・MIMEタイプ・送受信者IDはサーバーに送信される
- ファイル実体ではないが「誰が誰に何という名前のファイルを送ったか」はサーバーが把握可能
接続相手の確認手段がない(既知の問題)
- 合言葉を知っていれば誰でも受信者になれる
- 合言葉の安全な受け渡し(口頭・別チャネル経由)は利用者の責任
- 合言葉の推測攻撃のリスクあり(TTL10分で緩和されるが完全ではない)
TURN経由時のプライバシー
-
インターネット越しに使用する場合、NATトラバーサルが必要になりTURNリレーが 発生する可能性がある
-
TURN経由時はファイルデータがTURNサーバーを通過するが、DTLS暗号化は維持される (TURNサーバーは暗号化パケットを転送するだけで内容は読めない)
-
自己ホスト構成でTURNサーバーも自己管理する場合、第三者へのデータ通過は発生しない
-
第三者TURNサービス(coturn等をクラウドで動かす場合)を使用する際は そのサーバー管理者が暗号化データを通過させることを認識すること
結論
「ファイル実体がHyperDriveサーバーに保存されない」という意味では セキュアと言える。ただし「完全End-to-End暗号化でメタデータも保護される」 ではないため、「プライバシー重視のファイル直接転送機能」という表現が正確。
チャンク分割転送
大容量ファイルを転送する際の仕組み:
- WebRTC DataChannel の MTU 制限(一般的に16KB〜64KB/チャンク)
- リクエストの
chunk_sizeフィールドの役割- 合言葉共有 API(
POST /v1/files/watchword)のリクエストで送信者が希望チャンクサイズを指定する - 送受信ブラウザはこの値を基準にファイルを分割し、DataChannel 上で順次送信する
- 合言葉共有 API(
- 受信側でチャンクを結合してファイルを再構成する流れ
- チャンク0〜N を順次受信(またはシーケンス番号で並べ替え)
ArrayBuffer/Blobに結合- 受信完了後、
filehashとローカル計算ハッシュを照合
- 進捗表示のためのチャンク番号管理
- 各チャンクに連番(0始まり)を付与し、UI は
受信済みチャンク数 / 総チャンク数で進捗を表示する
- 各チャンクに連番(0始まり)を付与し、UI は