見出し画像

暗号化と似ているようで似ていない「ハッシュ化」について

皆さまこんにちは。2020年に新卒として株式会社コンピュータマネジメントに入社し、Webマーケティングを担当している入社4年目のMです。

前回記事では、映画「サマーウォーズ」に登場する「RSA暗号」にちなみ、暗号化の仕組みや種類について図解で分かりやすくご紹介しました。

今回は、通信の安全性を高める方法として「暗号化」とよく混同されがちな「ハッシュ化」についてお話ししていきたいと思います。


ハッシュ化とは?

ハッシュ化とは、「ハッシュ関数」と呼ばれる特殊な計算方法により、一見するとランダムに見える別の値(ハッシュ値)に元のデータを変換する方法です。

同じデータから生成されるハッシュ値は常に同一のものとなり、逆に元のデータの内容が少しでも異なれば、生成されるハッシュ値は全く異なるものとなります。

また、ハッシュ化は「不可逆的変換」のため、生成されたハッシュ値から元のデータに戻すことはできないというのも、大きな特徴の1つです。

これら「同一データのハッシュ値は常に同じである」「ハッシュ値から元のデータは復元できない」という性質を利用し、ログインパスワードの照合やデータ改ざん有無の確認など、今では様々な場面で使われています。

暗号化との違いは?

暗号化とハッシュ化の主な違いは、「元のデータに戻せるかどうか」です。

暗号化されたデータは、「暗号鍵」を用いれば元に戻す(=復号する)ことができますが、ハッシュ化されたデータは、ハッシュ化の作業を行った当人も含め、誰も元の状態に戻すことができません。

暗号化は後からデータを復号する前提で利用しますが、ハッシュ化は最初からデータの復号を想定していないため、両者が活用されるシーンは当然異なってきます。

パスワードのハッシュ化

ハッシュ化は「復元する必要のないデータ」に用いられます。その代表的な例が「パスワード」です。

ログイン機能を持ったサービスやアプリケーションでは、データベースにパスワードを保管しておき、ログイン時にユーザーの入力したパスワードが正しいものかどうかを照合します。

この時、データベース内にあるパスワードは、元の文字列(平文)のままではなく、ハッシュ化した状態で保管されます。
パスワードがハッシュ化されていれば、万が一パスワードが流出したとしても元の状態に復元できないため、第三者による悪用を防ぐことができるからです。

ログイン時は、「入力されたパスワードから生成したハッシュ値」と「データベースに格納されているパスワードのハッシュ値」が同一かどうか確認すれば良いので、わざわざパスワードを元の平文に戻す必要もありません。

このように、パスワードをハッシュ化することで、秘匿性を保ったまま安全なログイン認証を実現することができるのです。

パスワード再設定のナゾ

皆さんは、何らかのWebサイトで会員登録を行い、時間が経ってから再度ログインしようと思った時に、「パスワードを忘れてログインできない!」となったことはありませんか?(私はしょっちゅうあります)

この時、多くのWebサイトでは、パスワードを忘れた場合の対処法として「パスワードをリセットして再設定する」方法が採られていると思います。

「なんで設定しているパスワードをメールとかで通知してくれないの?」と不思議に思うかもしれませんが、実はこれはパスワードをハッシュ化して管理しているからなんです。

サイト側でパスワードをハッシュ化してデータベースに保管している場合、サイト側のほうでもパスワードは復元できず、元々設定していたパスワードが何なのかユーザーへ通知することができないため、パスワードのリセットと再設定が必要になるというわけです。

ハッシュ化の弱点

パスワードの管理などに用いられるハッシュ化ですが、決して万能というわけではありません。

元の値とそれに対応するハッシュ値をあらかじめリストアップして表(テーブル)にしておき、順番に当てていく「レインボーテーブル」と呼ばれる方法を使えば、ハッシュ値から逆算して本来のパスワードを簡単に推測されてしまいます。
「同じデータから生成されるハッシュ値は常に同一のものとなる」という、ハッシュ化が持つ特徴の隙を突いた巧妙な攻撃手法です。

このような攻撃手法に対応すべく、一般的にハッシュ化の際は、以下3つのような工夫が施されることが多いです。

対策その1:ソルト

「ソルト」とは、ハッシュ化する前のパスワードに付与する任意の文字列のことです。

「ソルト」を付与することで、元々同じパスワードでも出力されるハッシュ値は全く異なるものになるため、あらかじめリストアップしたハッシュ値から本来のパスワードを推測しようとするレインボーテーブル攻撃への対策として非常に有効となります。

対策その2:ペッパー

「ペッパー」とは、ハッシュ化する前のパスワードに付与する固定の文字列のことです。「ソルト」がパスワードごとに異なるのに対し、「ペッパー」はすべてのパスワードに共通の値が付与されます。

「ペッパー」は「ソルト」と組み合わせることで、より強力なセキュリティ効果を発揮します。

「ソルト」はパスワードのハッシュ値と同じデータベースに保管されることが多く、ここから情報が漏えいするとハッシュ値とセットで「ソルト」も第三者に知られることになり、簡単にハッシュ値からパスワードを推測されてしまいます。

一方、「ペッパー」はハッシュ値とは別の階層(データベース以外の場所)に保管されているため、同時に情報が流出することはありません。
「ペッパー」が第三者の手に渡らない限り、ハッシュ値からパスワードを割り出すのは困難になるというわけです。

対策その3:ストレッチング

「ストレッチング」とは、ハッシュ化を複数回にわたって繰り返し行うことです。何度もハッシュ化を繰り返すことで、パスワードの推測をより困難なものにします。一般的には数千~数万回ほどストレッチングを行います。

ストレッチングの回数を増やせば増やすほど、レインボーテーブル攻撃によるパスワード解読までの時間を引き延ばすことができますが、その分PCへの負荷が増加して処理速度も遅くなるので、コンピューターに負荷が掛かりすぎない範囲で徐々にストレッチング回数を増やしていくのが理想的です。

まとめ

今回は、「暗号化」とよく混同されがちな「ハッシュ化」についてご紹介しました。

調べていて、パスワードリセットと再設定のカラクリがハッシュ化にあったとは驚きでした。意外と身近なサービスに使われているものなんですね!

それでは今回はこの辺で。次回のnoteもお楽しみに!
ここまで読んでいただき、ありがとうございました!


この記事が気に入ったらサポートをしてみませんか?