わさっきhb

大学(教育研究)とか ,親馬鹿とか,和歌山とか,とか,とか.

ソルトとベルト

Unixパスワード管理における,「ソルト」の役割について,説明します.

ソルトがないとき

まずソルトがない状態で,暗号化パスワードは,パスワードのみに依存して求めるのだと,どんな不都合が起こるかを考えてみましょう.
例えば,ユーザ名がtakehikoで,パスワードがwakayamaとします.そしてある暗号化関数で,nNAvIrX23n2という文字列が作られたとします.
次に,ユーザ名がmurakawaという人が,たまたまwakayamaというパスワードを選んだとします.そうすると,暗号化関数でできるのは,「パスワードのみに依存して求める」といいましたので,nNAvIrX23n2ですね.
さて,そのようなユーザ情報と暗号化パスワードがファイルになっているのを,たまたま見ることができたら,どうかと言いますと,ユーザtakehikoとユーザmurakawaは,パスワードは何か分からないけど,同じものらしいということが言えますね.
もしそのたまたま見た人が,takehikoさんだったら,もっとすごいことになります.murakawaのパスワード,自分と一緒じゃないか! となります.だからログイン時に,takehikoさんが,ユーザ名にmurakawa,パスワードに自分用の文字列,ここではwakayama,を入力すれば,takehikoさんなのにmurakawaさんとして認証されてしまうということになります.
これは情報セキュリティの三大要素のうち,完全性を脅かすものとなります.

ソルトがあるとき

そこで「ソルト」が登場します.実際のUnixのパスワード管理では,crypt関数は,パスワード文字列そのものと,ソルトという文字列を引数にとります.ソルトというのは「塩」です.振りまくことで,味わいが変わる,という意味合いらしいです.そういえばプログラミングの世界では,シンタックスシュガーとか,スパゲッティプログラムとか,食べ物にちなんだ表現がありますね.
それはそれとして,takehikoさんのパスワード登録の際に,パスワードにwakayamaを選んだとしましょう.そしてシステムでは…ここでの「システム」は「ユーザが行うのではない」という意味合いです.登録の何らかのソフトウェアですね…ランダムに文字列を選びます.古典的なUnixのパスワード管理*1では,英語の大文字と小文字,数字,それとピリオドとスラッシュの中から,重複を許した2文字をひとつの文字列として,ソルトとします.ccがソルトになったとしたら,wakayamaとccから,ccwp5gV6wOumkなんていう,暗号化パスワードが作られたりします.
先頭2文字は,ソルトそのままです.認証の際,「入力されたパスワード」と「暗号化パスワードに含まれるソルトの部分」を用いてcrypt関数を適用し,できあがる文字列が暗号化パスワードであるかどうかでもって,入力されたパスワードが正しいかどうかを判定するわけです.
次に,murakawaさんでしたね.やはりパスワードにwakayamaを選んだとき,システムが今度はseというのをソルトに選んだとします.そして暗号化パスワードはseL7HUUbt2qmAなんてのになりました.
ここでソルトがないときと同様に,たまたまユーザ名と暗号化パスワードの情報を知ることができてしまったとしましょう.takehikoさんの暗号化されたパスワードはccwp5gV6wOumk,そしてmurakawaさんのはseL7HUUbt2qmA.これから,2人のパスワードが同じであることが,推測できないというわけです.
このように,ソルトが異なれば,同じパスワードでも,異なる暗号化パスワードが生成されるわけです.

ソルトが同じなら,暗号化パスワードも同じ?

そうすると一つ,気になることがありますね.同じパスワードで,同じソルトなら,同じ暗号化パスワードになるのではないか,と.
これは確かにその通りです.なのでそうなりにくいように,ソルトになり得る集合すなわち「ソルト空間」を大きくすればいいのです.
先ほど,ソルトとして使われる文字のことを言いましたね.「古典的なUnixのパスワード管理」という条件をつけますが,そこでは,英語の大文字と小文字,数字,それとピリオドとスラッシュでした.何文字ありますか? …64文字ですね.その中から重複を許して2文字ですから,64の2乗,というか「2の6乗」の2乗ですから,指数法則で2の12乗となって,4096種類です.
なので,2人のユーザが同じパスワードのとき,同じ暗号化パスワードになる確率は,同じソルトが選ばれる確率,すなわち4096分の1となります.
分数で,そうなる理由を確認しましょうか.確率を求める際の,分母すなわち全ての場合の数については,1人目のソルトは4096通り,2人目のソルトも4096通りあって,独立していますからかけ算で,4096の2乗です.分子は,ともにソルトがaaになる場合,ともにabになる場合,acになる場合…と考えてみると,「1人目のソルトがxで,2人目がそれと同じになる」という組み合わせになり,xは任意のソルトですから,4096通りです.分母が4096の2乗,分子が4096ですから,約分して,確率は4096分の1というわけです.
システムがランダムに選ぶソルトに関して,約4000分の1です.そして2人が同じパスワードを選ぶのが分かる可能性は低いことと合わせれば,別々のユーザだけど同じ暗号化パスワードというのを見つけるのは,うんと低いと言っていいでしょう.
ただその一方で,確率を上げる要素というのもあったりします.安直なパスワードを選ぶ人がいることは,否定できませんね.そしてこっちのほうが要注意なのですが,「特定のユーザのパスワードを知りたい」ではなく「暗号化パスワードが同じになる2人なら誰でもいいから知りたい」と目標を切り替えると,ソルト空間の平方根の個数を考えます.ここではルート4096ですから,64ですね.何かというと,64個の暗号化パスワードがあれば,その中にソルトが一致するものが出てきやすくなります.
これはバースデイアタックと呼ばれ,一方向ハッシュ関数の強衝突耐性において,考慮しないといけないものです.64を多いと見るか少ないと見るかは,見る人次第ですかね.何度か「古典的なUnixのパスワード管理」と言ってきましたが,MD5やBlowfish,SHAなんとかをベースとする,現在の実用的なパスワード管理では,この「ソルト空間」は,4096よりももっと大きくなっていて,バースデイアタックを働きにくくしています.

ベルト

ちょっと,余談です.初回授業のとき,僕は海外に行っていたというのはすでにお伝えしたとおりですが,その中で,ちょうどこのパスワードとソルトに似たものを,見つけたのでした.
日帰りや1泊なんてのではなく,1週間前後,海外へ行くのですから,スーツケースにいろいろ入れて,機内持ち込みではなく荷物*2として預けるのは当たり前のことです.着いた空港の,baggage claimなんてところで,ベルトコンベヤに乗ってがらがらがらと,たくさんの荷物に紛れて,自分の荷物を見つける必要があります.
そういった状況で,自分の荷物を的確に見つけるには,どうすればいいでしょうか? 目を良くするというのは一つの手ですが,そこは人によります.別の方法を考えましょう.
スーツケース見りゃ分かるじゃないか,というのは,素朴な発想ですね.映画なんかだったらありますかね,角張ったケースで,古びているように見えるけどたくさんの旅行に持っていったことの証でタフなようで,シールをたくさん貼っているような.とはいえ旅慣れていない我々が,そんなスーツケースを用意するというのは難しいものです.
他の人が選びそうにないスーツケースを選ぶ,というのは良さそうです.しかしそれでも,お気に入りの,形状だとか色だとかが特殊なものと,全くあるいはほぼ同じで,だけど自分のじゃなかったという可能性は,ないとも限りません.
そこでスーツケースに,旅行用のベルトを組み合わせるというのが,現実的なやり方となります.ベルトもまた,お気に入りでいいでしょう.旅行用品を扱っているところのほか,空港内の売店でも,見つけることができます.スーツケースとそのベルトの組み合わせで,たまたまのたまたま,一致するけど自分のではないという確率は,うんとうんと低くなるという次第です.
ここで,スーツケースとベルトの組み合わせを,パスワード管理に見立てることができるのです.暗号化パスワードのうち,ベルトがソルトで,スーツケースがソルトの後の部分です.ついでに,中身の荷物は,認証されてサービスを受けられることに,対応付ければいいのでしょうかねえ.
まあ空港の手荷物の場合は,勘違いだとか故意だとかで,他の人の荷物を手に取ることができてしまいます.それは名札をつけるだとか,預けるときに受け取る「クレームタグ」をきちんと持っておくだとか,空港の人があちこちで目を光らせるだとかで,対処するとしましょう.
では,まとめです.
パスワード管理では,暗号化パスワードを含む情報が悪意のある人に知られてしまっても,そこからパスワードが推測されてはいけません.ソルトを導入することで,多数ある暗号化パスワード情報の中に,「これとこれのパスワードは同じだな」と思われる可能性を小さくすることができます.
空港の,スーツケースとベルトの組み合わせは,ベルトコンベアに乗る多数の荷物の中で,「これは私のではない,これも違う,…これが私のだ!」と識別しやすくなるわけです.私にとっても,他の旅客にとっても,識別しやすいということは,見かけの同じ2つの手荷物が出てくる可能性を小さくすることと同じなのです.

感想

授業終了後に,出席確認を兼ねたメモを整理して見かけた,ある学生の感想:
「スーツケースとベルトの話は興味深かったです.ただ旅行経験の少ない学生にとっては,携帯電話とストラップの組み合わせのほうが,わかりやすかったのではないでしょうか」

*1:http://www.linux.or.jp/JM/html/LDP_man-pages/man3/crypt.3.html, UNIXのユーザー認証 - Security Akademeia

*2:Googleによると,一般には「受託荷物」というのですね.Fly with Australia’s most popular airline | Qantas JPには,お客様向け用語として「お預け手荷物」と表記していますが.