ハッシュ(ハッシュ関数)とは|仕組み・種類・用途・セキュリティ対策と推奨アルゴリズム(SHA‑2 / SHA‑3 / Argon2)
ハッシュとは — 概要
ハッシュ(英: hash)は、任意長のデータを固定長の値に変換する「ハッシュ関数」によって得られる値を指します。IT分野では「ハッシュ値」「ハッシュ関数」「ハッシュテーブル」など、用途や文脈に応じて使われます。基本的には「入力データを短い識別子に変換する技術」であり、データの同定、整合性検査、パスワード保護、データ構造の効率化、ブロックチェーンの基礎など幅広く使われます。
ハッシュ関数の基本特性
- 決定性: 同じ入力は常に同じ出力を生成する。
- 固定長出力: 入力の長さに関係なく、出力は固定ビット長(例: SHA-256 は 256 ビット)である。
- 効率性: 計算は高速でなければならない(用途によっては高速性より遅延耐性が要求される)。
- 衝突の存在: 出力空間は有限なので、異なる入力が同じハッシュ値を持つ「衝突」は必ず存在する(鳩ノ巣原理)。
- 均一分布性(理想的な性質): 入力のわずかな差が出力全体に大きな変化をもたらすこと(アバランチ効果)が望まれる。
ハッシュの分類:暗号学的か非暗号学的か
用途によってハッシュ関数は大きく二つに分かれます。
- 非暗号学的ハッシュ:ハッシュテーブルや高速のチェックサム用途で使われる。例: CRC、MurmurHash、xxHash。高速だが衝突や攻撃に弱い。
- 暗号学的ハッシュ(Cryptographic Hash Function):衝突回避、前像耐性、第二前像耐性などのセキュリティ性を持つことが要求される。例: SHA-1(脆弱化)、SHA-2(広く使用)、SHA-3(Keccak)など。
暗号学的ハッシュ関数のセキュリティ要件
- 前像耐性(Preimage resistance): 与えられたハッシュ値から元の入力を見つけることが計算上困難である。
- 第二前像耐性(Second-preimage resistance): 与えられた入力と同じハッシュ値を持つ別の入力を見つけることが困難である。
- 衝突耐性(Collision resistance): 任意の二つの異なる入力で同じハッシュ値になるペアを見つけることが困難である。実際の計算量はビット長 n に対しておおよそ 2^(n/2)(誕生日攻撃)である。
代表的なハッシュアルゴリズム
- MD5:かつて広く使われたが、2004 年以降衝突が実証されており、セキュリティ用途では非推奨。
- SHA-1:2005 年頃から弱点が指摘され、2017 年に実際の衝突(SHAttered)が実証されたため、セキュリティ用途では非推奨。
- SHA-2(SHA-224/256/384/512 等):現在も広く使用されている家系。例えば SHA-256 は Bitcoin のブロックチェーンや TLS 証明書などで多用される。
- SHA-3(Keccak):NIST が 2012 年に選定し 2015 年に標準化。内部構造が SHA-2 と異なる代替アルゴリズム。
- bcrypt, PBKDF2, Argon2:パスワード保護用の鍵導出(KDF)/パスワードハッシュ。計算負荷やメモリ負荷を意図的に増やし総当たり攻撃を困難にする設計。
- SipHash, MurmurHash, xxHash:ハッシュテーブルや性能重視の場面で使われる高速非暗号ハッシュ(ただし SipHash は DoS 対策のためキー付きで安全性をある程度確保)。
ハッシュの主な用途
- データ整合性検査: ダウンロードファイルや転送データが改ざんされていないかを確認するためにハッシュ(チェックサム)を用いる。
- パスワード管理: 平文パスワードをそのまま保存せず、ソルトと共にハッシュ化して保存する。さらに bcrypt/Argon2 のような専用アルゴリズムが推奨される。
- データ構造(ハッシュテーブル): キーから配列インデックスを得るためにハッシュを利用し、平均 O(1) の検索を実現する。
- 重複除去・データ指紋: 大きなファイルをハッシュで比較して同一性を検出する(ただし衝突リスクを理解する必要あり)。
- コンテンツアドレス可能ストレージ: Git のオブジェクトや分散ストレージでは、データをそのハッシュ値で識別する設計が使われる(過去は SHA-1、移行が進む)。
- ブロックチェーンとマークルツリー: トランザクション整合性を保証するためにハッシュを連鎖的に利用。ブロックのハッシュ値がチェーンの一貫性を担保する。
- デジタル署名の前処理: 長いメッセージを直接署名するのではなく、まずハッシュ値を計算してから署名する(署名対象の短縮化と一貫性のため)。
- HMAC(キー付きハッシュ): メッセージ認証コード(MAC)を作るためにハッシュを鍵付きで用い、改ざん検知と認証を行う。
衝突と攻撃のリスクおよび対策
ハッシュ関数は設計により安全性が大きく変わります。MD5 や SHA-1 のように衝突が容易に作れるアルゴリズムは、デジタル署名や証明書、パッケージ署名の用途では深刻なリスクを生じます。対策としては:
- 安全性が確認されたアルゴリズム(現状では SHA-2, SHA-3)を使用する。
- パスワードは単純ハッシュでなく、ソルト+KDF(bcrypt, Argon2, PBKDF2 等)を使う。
- 非暗号学的ハッシュをユーザ入力のキーとして公開 API に直接使わない(ハッシュテーブル攻撃対策として SipHash 等を採用)。
- 重要な用途ではハッシュだけに依存せず、複数の検査や署名、タイムスタンプ等と組み合わせる。
実装・運用上の注意点
- ハッシュ長の選択: 長いほど衝突探索が困難(計算量は 2^(n/2))だが、長すぎるとストレージや帯域に負担。
- エンコーディングと正規化: テキストデータは UTF-8 などで統一してからハッシュ化しないと異なるバイト列になり不整合が生じる。
- ソルトとパラメータ管理: パスワードハッシュではソルトをユニークにし、KDF のコストパラメータを定期的に見直す。
- 移行計画: 脆弱なハッシュを使っている場合、アルゴリズム移行計画(例: SHA-1 → SHA-256、MD5 廃止)を準備する。
具体例(短いデモ)
同じ入力文字列 "hello" の代表的なハッシュ値(16 進表記)を示します。
- MD5("hello") = 5d41402abc4b2a76b9719d911017c592
- SHA-1("hello") = aaf4c61ddcc5e8a2dabede0f3b482cd9aea9434d
- SHA-256("hello") = 2cf24dba5fb0a30e26e83b2ac5b9e29e1b161e5c1fa7425e73043362938b9824
(出典: 標準的なハッシュ実装に基づく値)
最新動向と今後の展望
- SHA-2 が現行の主流だが、SHA-3(Keccak)や新しい KDF(Argon2)が各分野で採用されつつある。
- 量子コンピュータの進展は公開鍵暗号に大きな影響を与えるが、ハッシュ関数に対する影響は相対的に小さい(Grover のアルゴリズムにより N ビットのハッシュはおおむね 2^(N/2) から 2^(N/2) に影響するため、出力長を増やすことで対処可能)。ただし長期的には注意が必要。
- 実運用では「脆弱アルゴリズムの撤廃」「パスワードハッシュの強化」「ハッシュベースの識別(CAS)のセキュリティ設計」が継続的な課題である。
まとめ
ハッシュは短い固定長の「データの指紋」を作るための基本技術で、データ整合性、データ構造、セキュリティ機能など幅広い用途に不可欠です。しかし、用途に合わせて適切なアルゴリズムを選び、既知の脆弱性や衝突リスクに対する対策(安全なアルゴリズムの採用、ソルトや KDF の使用、移行計画など)を講じることが重要です。


