BitTorrent Sync のシークレットキーに関する考察
BitTorrent Sync は、チョー大まかに言うと
- デバイス
A
で、共有したいフォルダf
の シークレットキー を生成する - デバイス
B
で、f
と同期したいローカルのフォルダf'
と、先ほど生成した シークレットキー を設定する
というたったの2ステップで、デバイス A
・ B
の f
・ f'
を同期させることができる。
実際使ってみるとチョーお手軽。
で、「この仕組みって本当に安全なの?」という素朴な疑問が生まれる。 だってたった一つの、高々数十Byteの文字列を知ってさえいれば、他人のデータだろうが難なく読み取ることができちゃうわけで。 狙って攻撃できたり、そうでなくてもうっかり衝突しちゃったりとかしないの?
やっぱり皆おっかなびっくりらしく、フォーラムでも疑問の声は上がってたりする。 そうだよねぇ。
- Security - Sync General Discussion - BitTorrent Forums
- Can someone just guess shared secrets? - Sync General Discussion - BitTorrent Forums
で、自分でもちょっと調べてみた。
適当なこと言ってるかもしれないので、デベロッパ向けのドキュメントやユーザガイドも是非読んでみてください。 で、間違いとかあれば指摘していただけると‥‥。
シークレットキーの実際
シークレットキーの長さは仕様上、 20 byte (160 bit) もしくはそれ以上と決まってる。
自動生成すると33文字の英数字から成る文字列ができるけど、頭1文字はどうやら便宜上権限を示すらしく、実際のキーは残りの32文字。この文字列、可読性を上げるために Base32 エンコードされたものなので、 32 byte / 8 byte * 40 bit
で確かに 20 byte (160 bit) ある。
試しに自動生成してみたシークレットキーがこれ。
12345678901234567890123456789012
+--------+---------+---------+--
シークレットキー ACGT66NJPIFGVY6YI3GWCWJRYOBOK6XYN
読込専用シークレットキー BJFMTOC234PX35OZYG4FZP7IMJVJ5KWXM
読込専用 シークレットキーは、シークレットキーからさらに一方向なロジック (じゃなきゃ意味ないし) で自動生成されたもの。 これを知ってるとそのフォルダを読むことだけはできる。
あと ワンタイム シークレットキーというのもあるらしいけど、興味のある人は自分で調べてください。
シークレットキーは門外不出
プロトコル上、シークレットキーが生でネットワーク上を流れることはない。
その代わりに SHA1(Secret):ip:port
みたいなシークレットキーのハッシュ値を含んだ情報を各ピアが発信して、P2Pネットワークの中で同じシークレットキーを持ってるピアを探し出してる。
さらにピア同士は、お互いが知っているシークレットキーから生成した AES 暗号鍵を使ってデータをやり取りするので、シークレットキーを知らないピアが相手をだまくらかしてデータを盗むことは理論上不可能。
ピア同士のネットワーク構成によっては第三者ピア (リレーサーバ) を経由したりすることもあるらしいけど、基本はやっぱり一緒。
シークレットキーは十分長い
たとえば「地球上のすべての砂粒にIPアドレスを振ってもまだ余る」 (大学の講義で某エラい人が言ってた) と評される IPv6 のアドレス空間は 128bit 。これはつまり、
2^128 =
340282366920938463463374607431768211456 (約340潤) 個
のアドレスが存在し得るということ。
一方で BitTorrent Sync のシークレットキーは前述の通り (最小) 160bit。つまり、
2^160 =
1461501637330902918203684832716283019655932542976 (約1.5極) 個
のシークレットキーが存在し得るということ。ちなみに 極 は 10^48 で、恒河沙の一つ下。ごうがしゃて。
さぁクラックしましょう。 地球上のすべての砂粒の 4294967296 倍よりもさらに多い砂粒の中からお目当ての一粒を探し出すには、仮に人手をかき集めて一秒に千粒チェックできたとして、果たして何年かかるでしょうか?
2^160 / 1000 / (60 * 60 * 24 * 365) =
46343912903694283301740386628497051612 年
ざっと46澗年かければ見つかりますね。半分くらいでヒットすると期待しても23澗年くらい。 余裕で人類滅ぶ、というか地球が太陽に呑まれてるわ。
次に、仮に全世界で十億個のフォルダが既に共有されているとして、ランダムで自動生成した一個のシークレットキーがうっかり他のフォルダのシークレットキー (読込専用も含む) に一致しちゃう確率は、
2 / 2^160 * 1000000000 =
約 0.0000000000000000000000000000000000001 %
730潤回くらい生成してると、少なくとも一つはヒットしちゃう計算ですね。 730かんかいて。
まとめ
乱数生成器が高品質な乱数を生成していて、 BitTorrent Sync の実装にバグがない限り、シークレットキーは十分な計算量的安全性を持ってるはず。 ただし所詮は確率計算上の話なので、世界のどこかで誰かが今頃うっかり俺のシークレットキーの一つを生成しちゃってて、身に覚えもなく落ちてきた大量の写真を見てしきりに首を傾げてるかもしれない。 そして俺は逆に、あまりのラッキーさに感激して失禁しちゃうはず。
まぁマジメな話、シークレットキーはデバイス本体と同じくらい本気で守りましょう。 平文でネットワークに流さないとか、物理的な紛失に注意するとか、そういう基本的なことだけど。 あと、できるだけ小分けしたり読込専用キーを上手く使って、必要なデバイスに必要なキーだけ入れるよう心がけると、万一の際に被害を最小限に抑えられるかと。
「もしや、キーが漏れたかも」と不安に駆られた時は、落ち着いて全部のデバイスのシークレットキーを変更して回りましょう。 少なくとも変更し終わった瞬間からは、再び1.5極の砂粒に潜ることができます。