ハッシュ値

任意の長さのデータを固定長の値に変換したもの。データの一意性検証や改ざん検知に使われる。

ハッシュ値とは、ハッシュ関数を用いて任意の長さのデータから生成される固定長の値です。同じ入力からは常に同じハッシュ値が得られる一方、ハッシュ値から元のデータを復元することは計算上極めて困難です。この一方向性がハッシュ関数の最大の特徴であり、セキュリティやデータ検証の基盤技術として広く利用されています。

代表的なハッシュアルゴリズムには MD5 (128 ビット出力)、SHA-1 (160 ビット)、SHA-256 (256 ビット)、SHA-3 などがあります。MD5 は 1991 年に設計され長年使われてきましたが、2004 年に衝突攻撃が実証されて以降、セキュリティ用途では非推奨となりました。SHA-1 も 2017 年に Google と CWI アムステルダムの共同研究が実際の衝突 (異なる 2 つの PDF が同じハッシュ値になる例) を示し、現在では SHA-256 以上の使用が推奨されています。ただし非推奨とされるのはあくまで「悪意ある改ざんを防ぐ」用途で、転送中の破損検知やキャッシュキーの生成といった攻撃者を想定しない場面では、計算が速い MD5 が今も実用的に使われています。用途がセキュリティかどうかで選ぶ、が実務上の判断基準です。

ハッシュ値の活用場面は多岐にわたります。パスワードの保存では、平文ではなくハッシュ値を保存することで、データベースが漏洩しても元のパスワードが直接露出するリスクを軽減できます。実務ではソルト (ランダムな文字列) を付加してからハッシュ化する手法が標準的で、bcrypt や Argon2 といった専用アルゴリズムが推奨されます。ここで SHA-256 を単体で使うのが不適切なのは、SHA-256 が「速い」ためです。総当たり攻撃側も同じ速さで試行できるので、意図的に計算を遅くする仕組み (bcrypt のコスト係数、Argon2 のメモリ量) を持つアルゴリズムを選ぶ必要があります。ファイルの整合性検証では、ダウンロードしたファイルのハッシュ値を公式サイトの値と比較することで、改ざんや破損を検出できます。

ブロックチェーン技術ではハッシュ値が中核的な役割を果たしています。各ブロックが前のブロックのハッシュ値を含むことでチェーン構造を形成し、過去のデータを改ざんすると後続のすべてのハッシュ値が変わるため、不正を検知できる仕組みになっています。Git のバージョン管理でも、コミットやファイルの識別に SHA-1 ハッシュが使われています。

ハッシュ値に関するよくある誤解として、「ハッシュ化は暗号化と同じ」というものがあります。暗号化は鍵を使って元のデータを復元できる可逆的な処理ですが、ハッシュ化は不可逆です。また、「ハッシュ値が同じなら元のデータも同じ」とは限りません。異なる入力から同じハッシュ値が生成される現象を衝突 (collision) と呼び、衝突耐性はハッシュアルゴリズムの安全性を評価する重要な指標です。

文字数カウントの観点では、ハッシュ値は常に固定長の 16 進数文字列として表現されます。MD5 なら 32 文字、SHA-256 なら 64 文字と、アルゴリズムによって出力の文字数が一意に決まります。入力データが 1 文字でも 1 GB のファイルでも、出力される文字数は変わりません。この固定長という性質は、データベースのカラム設計やログフォーマットの設計において、格納領域を事前に確定できるという実務上の利点をもたらします。具体的には SHA-256 を 16 進数文字列で持つなら 64 文字固定なので CHAR(64)、バイナリのまま持つなら 32 バイトで済み、格納量は半分になります。可変長の VARCHAR で確保する必要はありません。

実務での落とし穴もあります。16 進数表記には大文字と小文字の 2 通りがあり、同じハッシュ値でも文字列としては不一致になるため、比較の前にどちらかへ揃える処理を入れておかないと「値は合っているのに検証が通らない」事故になります。また Git がコミット ID を 7 文字程度に短縮して表示するように、ハッシュ値は先頭数文字だけを識別子として使うこともありますが、短縮すれば当然衝突しやすくなります。リポジトリが育つと 7 文字では足りなくなり、Git 自身も必要に応じて表示桁数を増やします。短縮ハッシュは表示用、照合には全桁、と使い分けるのが安全です。

この記事を共有