Misc Change Log

`OpenBSD で scheme のアプリ開発' みたいなことをやってます。

2005-03-04

hashcash - DOS ベースのアンチスパム技術

世の中にはいろんな人たちがいる。 その中でも、あなたにとってコミュニケーションをとる価値のある人と、 あなたの意思に関わりなくメッセージを読ませたがる人がいるのではないかと思う。

もちろん、あなたが必要としているのは前者であって、後者ではない。

それを振り分ける技術が、 メールだったらホワイトリスト/ブラックリストだったりベイジアンフィルタだったりするわけだ。

でも、こういった技術はかなり広汎に試されているので、ここで説明するのは置いておいて、 今回はもう少し変わり種の手法である hashcash を紹介しよう。

ここで、突然ちょっとした数学の話になる。 まあそんなに難しくはないので、最後までお付き合い願いたい。

ある文字列 S が与えられたとき、もうひとつの文字列 s と連結した文字列(トークン) S + s の ハッシュ値 H の 左 n bit がすべて 0 になる、そのような s はどんな文字列だろうか。

計算してみないとわからないって? そう。実際に s を 0 から順に H を計算して、 実際にそうなっているのかどうか確かめてみなければわからない。ここがミソ。

あなたがスパムメールにうんざりさせられているのなら、 この条件を満たす H のスタンプの入ったメールのみ読めばいい。 とうぜん、あなたの友人の同意も必要だけど。

久しぶりにメールのやりとりをしたいと思い立ったあなたの友人も、 毎週メッセージを替えて送ってくるスパマーも、 誰もが衝突するハッシュを発見するまで計算しなければならない。 「私と会話したいなら、ちょっとだけあなたの電力と時間をください」というのが、 hashcash なわけ。 個人の間でメッセージをやりとりするなら計算は 1 回きりだけど、 スパマーは大量にメッセージをまき散らさないといけないから、 それこそ何度も何度も違うハッシュを計算しないといけなくなる、というしかけだ。

それでは、実際どうなっているのか hashcash の公式ページからダウンロードして試してみよう。

コンパイルできただろうか? それではさっそく n = 20 で s を検索してみよう。

$ hashcash -mb20 foo
hashcash token: 1:20:050303:foo::kN687vWdyW8jUw3+:0000000000000072LM

しばらく計算した後、上のようなトークンが出力される。 実行するごとに乱数でかき混ぜるのでトークンのエントリの真ん中より右側は毎回違う値が出力されるはずだ。 ちなみに、いちばん右の 0000000000000072LM が s に相当する文字列である。

foo は他の人のトークンとぶつからないように、 実際に使用するときはユニークな文字列の方がいいだろう。 例えばメールアドレスのような。

本当にこれが正しいトークンなのか確かめてみよう。

$ echo -n "1:20:050303:foo::kN687vWdyW8jUw3+:0000000000000072LM" | \
openssl sha1
000004a5a3839d2d4e696d2ec4af01cf6340cfba

左 20 bit が 0 になっているのがわかるだろうか。

以上で原理が理解できたと思う。

次に応用なのだが、 javascript で実装してみたのがこれ。

token:
sha1:

javascript は実行速度が遅いので n = 10 である。

これを使って、 このページの くっつき BBS と連携させてみたので試していただきたい。

検索空間は 0 から 210 なので、 もしかすると衝突を発見できないかもしれない。 そのときは発見するまで計算ボタンを気が済むまで連打してほしい。

確認しておくけど、計算結果であるトークンは一回きりしか使えないことに注意。 なぜだかわかるよね? それを実現するためには毎回データベースへ使用済みトークンを登録していけばいい。

最後に、ここまで読んでくれた人への宿題。

リンク

Posted at 13:26 | Permalink | Category | Comments