Blog
ソルト…お塩!?セキュリティ強化手法「ソルト付きハッシュ化」とは?
セキュリティ強化手法「ソルト付きハッシュ化」とは?
そもそもハッシュ化とは
めちゃくちゃ基本的なことではあるんですが、ここから理解を深めたいと思います。
ハッシュ化とは特定のルール(アルゴリズム)で、元のデータや文字列を不規則な文字列に変換することです。 ハッシュ化は不可逆であり、元のデータを割り出せないようになってます。
ウェブ制作に身近な例に当てはめると、会員サイトのログインパスワードは平文ではなくハッシュ化して管理されていることが一般的です。
(WordpressなどCMSではこのあたり仕組み化されているので、何も考えなくても良くなっています。)
ただ、このハッシュ化では不規則な文字列が生成されますが、同一のデータからは同一のハッシュ値が生成されるため、予め元データとハッシュ値を結びつけておけばその情報を元にハッシュ値から元のデータを割り出すことができてしまいます。
「予め元のハッシュ化前のデータとハッシュ値を結びつけておく」リストのことをレインボーテーブルと言い、これを用いた攻撃をレインボー攻撃、レインボーテーブル攻撃などと言うそうです
主流のハッシュ関数
ハッシュ関数で主流なものは以下の通りです。
- MD5※
- SHA-1※
- SHA-2
- SHA-3
- bcrypt
※MD5やSHA-1については脆弱性が指摘されており、基本的には使用を推奨されていません。
SHA-256やSHA-512であれば(いずれもSHA-2の規格)Javascriptネイティブでも出力できます。
各言語、それぞれに対応する関数が用意されています。
Node.jsの場合、cryptoというライブラリが用意されているので、そちらが利用できます。
Javascriptでハッシュ化を試してみる
codepenでJavascriptのハッシュ化を試してみました。
アルゴリズムはSHA-256を使用しています。
文字列を変えればハッシュも規則性が特定しづらい異なるものに変わりますが、同じ文字列で出力すると再読み込みしても同じ文字列で出てきてしまうことが確認できます。
ソルトとは?
ソルトは、パスワードなど原文に適当な文字列を追加してハッシュ化する手法です。
文字列は任意、もしくはランダム生成の文字列(ユーザーパスワードなどは一意かつ長いものが望ましい)です。
上記codepenで示す例のように、不特定文字列が追加されたハッシュ値は1文字目から全く異なる文字列となります。
パスワードをDBに保存する際にソルトを含めハッシュ化することでレインボーテーブル攻撃にも対応できるので、パスワード+ソルトのハッシュ化された文字列と、ハッシュ化されたソルトを保存します。
こうすると、万が一流出してしまった場合でも、パスワード毎に解析が必要になり、単純なハッシュ化と比較して解析に膨大な時間を要します。
ストレッチングとは
余談になりますが、ハッシュ化の際の手法でストレッチングというものもあったので紹介します。
ストレッチングはハッシュ化したものをさらにハッシュ化し、何重にもハッシュ化することでセキュリティを高めようというものです。
繰り返せば繰り返すほど解析に時間がかかり、万が一流出したとしても、解析に膨大な時間を要します。
ソルト+ストレッチングでかなりの強度を上げることができます。
ただ、回数が多くなればなるほど、比較照合する処理時間も長くなるため、応答速度にも影響が出てくると思われますので、闇雲にするというのはパフォーマンスに影響がありそうで、仕様との相談となりそうです。