よくわからないポエムみたいなタイトルで始まりましたが、DBに格納しているパスワードをどうやって守るかという話題です。
趣味のサーバを運用する際に、「ソルト」という単語はよく目にしていたのですが、あまりしっかりと意味をわかっていなかったので、まとめておきます。
そもそも何の話?
色々なWebサービスを利用する際に、IDやパスワードを登録することがあると思います。
それらを利用して、ログインをするわけですが、そのためにはどのIDがどのパスワードを利用しているのか、どこかに記憶しておく必要があります。
その際に、人間であれば脳の記憶を覗かれることは今のところないはずなので、「山と聞かれたら川と返す」みたいに、パスワードはそのままの言葉を覚えておけば良いのですが、コンピュータは記憶を覗かれる恐れがあります。
そのため、パスワードはそのままの言葉(平文)で記録しないことが望ましいです。
その記憶を覗く攻撃と、それに対する防御策をまとめるような話になります。
本題
対策ってどのようなものがあるの?
一般的にはパスワードをそのまま記憶するのではなく、ハッシュ関数をかけて難読化することが行われるようです。
例えば、 "exampleshikapassword" というパスワードにMD5関数でハッシュをかけると、以下のようなハッシュ値が得られます。
$ echo -n "exampleshikapassword" | md5sum
b91bb005b8360a26f06914e2515d72db -
そこで、データベースには "312386ed265cfda1b1e7a76a1d8b0ad3" という文字列を登録しておくことで、仮に記憶が取られても元々のパスワードがそのまま見られることがありません。
ログインする際にも、入力されたパスワードにMD5関数をかけることで照合します。
どうやって攻撃してくる?
ここで、攻撃者がどのように考えるかというと、このハッシュ値から元のパスワードを推測しようとします。
その際に、「レインボーテーブル」という本記事のタイトルの虹に相当するものを作るようです。
レインボーテーブルの説明は若干ややこしいのですが、おおよそ以下のようなイメージ と思っておりますが、誤りなどありましたらコメントなどでご指摘いただければと思います。
- 「元となるキーワード」となる単語を用意する
- このキーワードをハッシュ化して、ハッシュ値を得る
- ハッシュ値と解読したいパスワードのハッシュ値が一致するかを確認する
- 一致しなければ
- ハッシュ値に対して「還元関数」を適用して新たな「キーワード」を生成する
- 一致すれば
- キーワードが解読したいパスワードなので、解読成功
- これを繰り返して、「元となるキーワード」から生成される大量のハッシュ値を生成する
攻撃者目線での利点は、「元となるキーワード」からハッシュ値を大量に生成できるので、パスワード解読用のテーブルを圧縮できるところのようです。
ハッシュ値からまた新たなキーワードを生むという発想はよくやるなぁと思いますね。
虹をかけられないようにするには?
ここでソルトが活躍してきます。
ソルトとは、塩みたいにサーバ側でパスワードに対してランダムな文字を振ることでハッシュ値を変更するものです。
$ echo -n "salt_exampleshikapassword" | md5sum
d8dd9e126af8ebe4d3c2d902455dcc15 -
このソルトは、何種類か用意しておくことで同じパスワードでも異なるハッシュ値を生成することができます。
$ echo -n "salt1_exampleshikapassword" | md5sum
cb07656ef73ef021ae72906a2fd0b83b -
$ echo -n "salt2_exampleshikapassword" | md5sum
9d348d4fb73b96d8e72fb3926a1eb823 -$ echo -n "salt3_exampleshikapassword" | md5sum
bed92fbe5a7fe9c07e6ea451149f7a40 -
これにより先ほどのレインボーテーブルなどの攻撃用データベースの容量を増加させることができるため、攻撃が成功しづらくなるようです。
ただし、このソルトはIDごとに異なるものを利用するなどしておかないと、ソルト自体が解読されてしまってソルトの効果が薄くなってしまうようです。
お塩とはいえ、それぞれの人に合った味つけをしてあげることが重要ということですね。
感想
ソルトがどのような働きをしているのかあまりわかっていませんでしたが、意外と重要なものなのだなと感じました。
最近は多要素認証など、パスワード以外でもアカウントが保護されることが多く、もしかしたらそこまで重要ではない知識なのかもしれませんが、こういった基礎的なことを知っておくのも良いですね。