ハッシュ関数とHMACとは?データの指紋を作る仕組み

ワンタイムパスワードの数字を作る計算や、サービスがパスワードを保存するときの処理には、ハッシュ関数という仕組みが使われているのをご存じでしょうか。
本記事では、ハッシュ関数と、それを使うHMACという仕組みを解説します。
ハッシュ関数とは
ハッシュ関数は、どんな長さのデータを入れても、決まった長さの値を返す計算です。返ってくる値を、ハッシュ値と呼びます。
ハッシュ関数は、「出力の長さが決まっている関数」です。1文字の文でも、大きなファイルでも、出てくるハッシュ値の長さは変わりません。
同じデータからは、いつも同じハッシュ値が出るのが決まりです。データが1文字でも違えば、まったく違うハッシュ値になるため、データの「指紋」のように使えます。ダウンロードしたファイルが傷んだり書き換えられたりしていないかを、公開されたハッシュ値と比べて確かめる使い方がその例です。
安全のための2つの性質
セキュリティに使うハッシュ関数には、2つの性質が求められます。
1つ目は一方向性です。ハッシュ値から、それを出す元のデータを見つけることは計算上できません。
2つ目は衝突耐性です。同じハッシュ値になる、2つの違うデータを見つけることも計算上できません。これがあるので、ハッシュ値が同じならデータも同じだと判断できます。
パスワードの保存に使う
多くのサービスは、パスワードをそのまま保存せず、ハッシュ値に変えて保存しています。
ログインのときは、入力されたパスワードからハッシュ値を作り、保存しておいた値と比べます。一致すれば、正しいパスワードだと判断できるわけです。
保存されているのがハッシュ値だけなら、サービスからデータが流出しても、一方向性があるのでパスワードそのものはすぐには分かりません。ただし、短いパスワードや、よく使われるパスワードは、候補を片端からハッシュ値に変えて比べれば見つかってしまいます。長く推測しにくいパスワードを使い、サービスごとに変えることが大切です。
HMACとは
HMACは、ハッシュ関数と秘密の鍵を組み合わせて、データが改ざんされていないことと、鍵を持つ相手が作ったことを確かめる仕組みです。
仕様(RFC 2104)によると、HMACは、信頼できない通信や保存の途中で情報が損なわれていないかを確かめるための、共有の秘密鍵を使う仕組みです。
ハッシュ関数だけなら、誰でも同じ計算ができます。HMACは秘密の鍵を混ぜて計算するので、鍵を持っている人しか正しい値を作れません。
ワンタイムパスワード(TOTP)の計算にも、このHMACが使われています。サービスと認証アプリが同じ秘密の鍵を持ち、鍵と現在の時刻からHMACで値を計算して、そこから6桁の数字を取り出しているのです。