こんにちは。開発担当のマットです。
今回の記事で、ウェブサービス等の開発者がパスワードを安全に保存するための塩かけ(ソルト)の概念を説明したいと思います。
むかしむかし…
大昔、ウェブサービスにアカウントを作成した際、そのウェブサービスが登録したユーザ名とパスワードをそのまま保存しました。
データベースを覗いてみると、各ユーザのユーザ名とパスワードはそのまま見れていました。
user_name | password |
田中 一郎 | 123456789 |
山田 太郎 | hogehoge |
鈴木 花子 | qwertyuiop |
村田 次郎 | hogehoge |
もちろん、サイトがハッキングされてしまった場合、全ユーザのパスワードが丸見えです。
これを使って、ログインすることもできますし、ユーザ様が別のウェブサイトで同じパスワードを利用している場合、そのウェブサイトにもログインされてしまうことは考えられます。
とても、不安全な方法でした。
ハッシングで隠す
こういう問題が明らかになった時、多くのウェブサービスがハッシングを使うようになりました。
ハッシングとは?
ハッシングとは一方的の暗号関数です。
その関数にパスワードを渡したら、暗号された文字列が生成されます。
いくつかのハッシング・アルゴリズムは存在しますが、md5 というものを使ってみると、”hello” が “5d41402abc4b2a76b9719d911017c592” に変換されます。
特徴として、似たようなものを暗号化しても、その結果(ハッシュ)が全然違います。
例:
“bat” => 5f3f4681121b460e3304a1887f42f1c3
“cat” => d077f244def8a70e5ea758bd8352fcd8
“あいうえお” => 86deb27a32903da70a7b2348fcf36bc3
“あいうええ” => 5c6a3a46075a5617cd570ee1c583e528
パスワードを直接データベースに保存する代わりに、パスワードのハッシュを保存する時代になりました。
user_name | password |
田中 一郎 | 25f9e794323b453885f5181f1b624d0b |
山田 太郎 | 329435e5e66be809a656af105f42401e |
鈴木 花子 | 6eea9b7ef19179a06954edd0f6c05ceb |
村田 次郎 | 329435e5e66be809a656af105f42401e |
ユーザ様がログインする際、入力したパスワードを同じアルゴリズムでハッシングして、データベースで保存されているものと一致する場合のみ、正しいパスワードと言えます。
この方法で、データベースにパスワードを直接保存することなく、ウェブサービスを作ることはできるようになりました。
…ところで、ちょっとした問題はまだあります。見えますでしょうか?
ハッシングだけの問題
上記の例で、山田 太郎さんと村田 次郎さんは同じパスワードを使いました。
同じパスワードを使っているため、ハッシュも当然同じです。
つまり、サービスがハッキングされてしまった場合、パスワードはバレませんが、「山田 太郎さんと村田 次郎さんは同じパスワードを使っています」というのがバレてしまいます。
もし、山田 太郎さんのパスワードが別の方法でバレてしまった場合、村田 次郎さんのパスワードもわかってしまいます。
あと、多くのユーザ様がいる場合、重複が多いパスワードを推測することも可能になります。
“password1” や “12345678” など、多くの人が使いそうなパスワードはあるので、重複数が多いユーザはこういうようなパスワードを使っていると言えますね。
塩かけ(ソルト)で解決
調理する時、塩を少し加えるだけで味がグッと変わりますよね。
同じく、ハッシングをする時、パスワードだけではなく、「ちょっとした何か」を加えると、全く違う結果になります。
例として、2人のユーザが同じパスワード (“password123”)を設定するとします。
そのままハッシングすると、2人とも同じハッシュになりますが、ユーザAのパスワードに「abc」を付け加えてからハッシングして、ユーザBのパスワードに「xyz」を付け加えてからハッシングすると、2人とも全く違うハッシュになります。
この「ちょっとした何か」を「ソルト」と呼んでいます。
ソルトは乱数でも、ランダムな文字列でも大丈夫です。とにかく全てのユーザに違うソルトが振られたら問題ありません。
そうすると、仮に全員が同じ「password123」を設定したとしても、データベースに保存されるパスワードが全く違います。
user_name | salt | password |
田中 一郎 | PJTBCTwz | a021144f7dec828d515f372d6d239f5f |
山田 太郎 | 5g0VkWF1 | 19ead4c6deca667db146d9a1c478e4d6 |
鈴木 花子 | p9nfzkBT | 411fec4ff70554cded8b48ab9bc3b8c3 |
村田 次郎 | BoqWcL59 | 5487529bd4deb8003b6a46bbbaf03332 |
ユーザがログインする時、入力したパスワードにソルトを付け加えてハッシングすると、その結果が password として保存されている値と同じ場合、ログインをさせるという処理になります。
私のパスワードは安全ですか?
ご利用のウェブサービスが正しくソルト付けとハッシングをしているかどうかは判断しにくいですが、「パスワードを忘れました」などのリンクを押した場合、自分のパスワードがメールで送信されたら、安全に保管されていないと言えます。
パスワードを正しく取り扱っているウェブサービスはユーザのパスワードをわかる方法がないはずです。どこにも保存してはいけないデータとなります。
なので、ウェブサービスが自分のパスワードをメールで送信できる場合…アウトです。
ご注意ください。