WEBサービス創造記

WEBサービスを作ったり保守したりしてる人のメモブログです。

ハッシュ化について

      2015/08/11

WEBやネイティブアプリなどプラットフォーム問わずよく行われる処理としては、パスワードなどの機密情報のハッシュ化があります。
ここではハッシュ化の概要やその使いどころなどを振り返ります。

ハッシュとは

与えられた原文(平文)から固定長の疑似乱数を生成すること。
あるアルゴリズムにしたがってハッシュ化を行う処理のことを「ハッシュ関数」と呼ぶ。ハッシュ関数によって得られた値は「ハッシュ値」と呼ぶ。

例えばPHPのcryptというハッシュ関数で”test”という文字列をハッシュ化すると”098f6bcd4621d373cade4e832627b4f6″がハッシュ値となる。

$ php -a
php > echo crypt("test") . "\n";
$1$5y6TxS0.$yKwC4Y6lW.VVR20FZ2mk6.

ハッシュ関数は不可逆処理を施すため、ハッシュ値から元の値を割り出すことは極めて困難となる。
この点が復号処理を行うともとに戻すことができる暗号化との違い。

ハッシュ値の照合

下記のような手順で元の値とハッシュ値の等価性を照合する。

  1. 元の値をハッシュ化する
  2. 調べたい値をハッシュ化する
  3. 1と2のハッシュ値を比較する

ハッシュ化の用途

実際によく使われてるのは下記のようなケース。

データベースに保存するパスワードなどの機密情報の隠蔽
→ ハッシュ化してから保存しておけば、万が一データが流出してもからハッシュ値からはパスワードは割り出せない
サーバ・クライアント間での認証・照合処理
→ 入力側と出力側でハッシュ値を求め、一致しているかを確認することでデータの改竄などを検出できる(メールアドレス認証やCSRF対策に用いられることがある)

ソルトについて

パスワードを暗号化するときにソルトというランダムなデータを追加すると、ハッシュの不可逆性が向上し、ハッシュ値がさらに安全なものになる。

例えば、phpのmd5でハッシュ化すると、なんど平文として”test”を渡してもハッシュ値は変わらない。

php > echo md5("test") . "\n";
098f6bcd4621d373cade4e832627b4f6
php > echo md5("test") . "\n";
098f6bcd4621d373cade4e832627b4f6

これに、ソルトを付加してからハッシュ化することで、”test”のハッシュ値を変えることができる。

php > define("SALT", "va0bnpa1");
php > echo md5("test" . SALT) . "\n";
c3b2fb7847eb1c6c09c20f44d0594e1c

このようにソルトを付与してから不可逆処理を行うことで、同じ平文であっても算出されるハッシュ値は違ったものになるので、安全性が高まる。

※ここでは説明の便宜上md5関数を使いましたが実装の際にmd5は使わないようにしましょう。理由は下記です。

よく使われるハッシュ関数である md5() や sha1() は、なぜパスワードのハッシュに適していないのですか?

MD5 や SHA1 そして SHA256 といったハッシュアルゴリズムは、 高速かつ効率的なハッシュ処理のために設計されたものです。 最近のテクノロジーやハードウェア性能をもってすれば、 これらのアルゴリズムの出力をブルートフォースで(力ずくで)調べて元の入力を得るのはたやすいことです。

PHP: パスワードのハッシュ – Manual

中途半端だけど一旦ここまで。

参考資料

 - プログラミング , , ,