Leurent 氏の言ってることが、やっと分かってきた (気がする)。
APOP は
+OK Hello this is a random greeting. <11111.22222222222@example.org>
っていう挨拶 (11111 は pid, 22222222222 は時刻) から
md5("<11111.22222222222@example.org>mypasswd")
を計算して返すことで認証する。
MD5 はブロックごとに計算して、えーと、足すのかな。
で、ブロックが
<11111.222222222 22@example.org>m ypasswd
というように区切られるとすると、
<11111.22222222222@example.org>m
と同じハッシュ値を持つ 2 ブロックの文字列を作っておいて試せば、 パスワードの一文字目が分かるということらしい。
例えば、
<aaaaa.bbbbbbbbbbb@example.net>m
がそれと同じハッシュ値を持つとする。
そして
+OK All your base is belong to us. <11111.22222222222@example.org>
に対するクライアントの答えと
+OK All your base is belong to us. <aaaaa.bbbbbbbbbbb@example.org>
に対する答えが同じだったら「最初の一文字目は m だ!」となるわけ。
alnum に限るとすれば、[a-zA-Z0-9] の数 (62) かける 2 で、最大 124 回ログインさせるごとに一文字ずつ判明するんだな。
man-in-the-middle の可能性は、 サーバ側からの timestamp がちょうど良い長さになる可能性がどれだけだか知らないので 計算できないけど、そんなタイミングを待たなくても
「なんか x 回に 1 回 APOP が失敗するけど、サーバの調子が悪いのかなあ。……ま、いいか」
という寛容な人をしばらく追いかけていれば、パスワードが分かるかもしれない。
ってことなのか?
暗号学者とすれば MD5 なんて使ってられないよ、って言うのかもしれないけど、 普通そんなに何度も試せるのか?
うーむ……。
あと、対策としては APOP を使わないこと (ちゃんと SSL を使うとか?) の他に、 自ら 100 回に 1 度ほどしか正しいパスワードを使わないようにする、というのもある、かも? (んなわけないか)
http://cve.mitre.org/cgi-bin/cvename.cgi?name=2007-1558<br><br>あと当然、彼が言ってるとおり、RFC 違反なデータをはじくという対策もある。