ハッシュアルゴリズムの基礎と実務活用ガイド:衝突耐性・原像困難性からパスワード保存まで

ハッシュアルゴリズムとは — 基本の定義と役割

ハッシュアルゴリズム(ハッシュ関数)は、任意長の入力データを固定長の出力(ハッシュ値、ダイジェスト)に変換する関数です。入力が僅かに変わっても出力が大きく変わる「アバランチ効果」を持ち、同一入力は常に同一のハッシュを返す「決定性」を備えます。IT分野ではデータ整合性チェック、デジタル署名、パスワード保存、コンテンツアドレッシング、ブロックチェーンなど多岐に渡って利用されます。

ハッシュ関数に期待される主要性質

  • 固定長出力:入力の長さに関わらず出力は一定(例:SHA-256は256ビット)。
  • 決定性:同じ入力は常に同じハッシュ値。
  • 衝突耐性(Collision resistance):異なる入力が同じ出力になる(衝突)ことを見つけるのが難しい。
  • 第一原像困難性(Pre-image resistance):ハッシュ値から元の入力を見つけるのが困難。
  • 第二原像困難性(Second pre-image resistance):特定の入力に対して同じハッシュを与える別の入力を見つけるのが困難。
  • 効率性:計算が十分に速く、実用上使えること。

暗号学的ハッシュと非暗号学的ハッシュ

用途により2つに大別されます。暗号学的ハッシュは前述の衝突耐性や原像困難性を重視し、セキュリティ用途(署名、認証、パスワード保護など)に用います。非暗号学的ハッシュ(例:MurmurHash、xxHash)は高速でハッシュテーブルやデータ構造(Bloom filter、ハッシュマップ)向けで、攻撃者が衝突を作ることを想定しない用途に限定すべきです。

代表的なハッシュアルゴリズム

  • MD5:128ビット出力。衝突脆弱性が公開されており、セキュリティ用途では廃止が推奨。
  • SHA-1:160ビット出力。2017年に実際の衝突が示され(“SHAttered”)、署名やTLS等セキュリティ用途では非推奨。
  • SHA-2(SHA-224/256/384/512):現在も広く使われる標準(FIPS 180-4)。実用的な衝突は報告されていない。
  • SHA-3(Keccak、FIPS 202):内部構造がSHA-2と異なるスポンジ構造で、長さ拡張攻撃に強い。
  • BLAKE2 / BLAKE3:高速かつ安全性を重視した設計。BLAKE2は既に広く採用、BLAKE3は並列性能と可変長出力が特徴。
  • RIPEMD, Whirlpool:その他の暗号学的ハッシュ。
  • パスワード用KDF(派生関数):PBKDF2、bcrypt、scrypt、Argon2(Password Hashing Competitionの優勝)。単純なハッシュはパスワード保存に不適切で、これらの遅延/メモリハード関数が推奨される。

実際の利用例と適切な選択

  • データ整合性チェック(ファイル検証、ダウンロード):SHA-256やSHA-3が妥当。MD5/SHA-1は衝突の懸念から避ける。
  • デジタル署名、証明書:SHA-2以上の暗号学的ハッシュと組み合わせる。
  • パスワード保存:Argon2が現時点で推奨。bcrypt/scryptは良い代替。単純なSHA-256等は避け、必ずソルト+遅延/メモリ制約を導入する。
  • HMAC(メッセージ認証):HMAC-SHA256等で署名・改ざん検知。HMACは長さ拡張攻撃の問題を緩和する。
  • コンテンツアドレス(Git、IPFS等):衝突リスクを考慮して設計されているアルゴリズムを選択。
  • ブロックチェーン、Merkleツリー:Bitcoinは二重のSHA-256(double SHA-256)を採用。MerkleツリーやProof-of-Workではハッシュの性質が安全性・性能に直接影響。

攻撃手法と既知の脆弱性

代表的な攻撃には以下があります。

  • 衝突攻撃:異なるメッセージで同じハッシュを見つける攻撃。MD5は既に実用的な衝突生成法が知られ、SHA-1も実際の衝突が作られています(Google/CWIによる2017年の報告)。
  • 長さ拡張攻撃:Merkle–Damgård構造のハッシュ(MD5、SHA-1、SHA-256等)に対して入力の末尾を付け足してハッシュを計算できる攻撃。HMACやSHA-3はこの種の問題に対する対策となります。
  • 辞書・総当たり攻撃:ハッシュだけでは低エントロピーのパスワードは簡単に解かれるため、ソルトやストレッチングが必要。

パスワード保存のベストプラクティス

  • 専用のパスワードハッシュ関数(Argon2が第一候補)を使う。
  • 各ユーザーに一意のソルトを付与し、ストレッチング(複数ラウンド)やメモリ負荷を設定する。
  • 定期的にアルゴリズムやパラメータを見直し、必要なら再ハッシュ(re-hash)する。
  • 比較時は定数時間比較を行いタイミング攻撃を防ぐ。

実装上の注意事項

暗号実装は誤りが致命的です。以下に注意してください。

  • 既存の信頼できるライブラリ(OpenSSL、libsodium、BoringSSL、言語標準の暗号ライブラリなど)を利用する。
  • 暗号学の知識なしに独自設計や簡易的な「秘匿化」を行わない。
  • ランダム生成には暗号学的乱数生成器(CSPRNG)を用いる。
  • プロトコル設計では、長さ拡張やマルチプレクシングによる副作用を理解する。必要ならHMACやAEAD(認証付き暗号)で対応。

まとめ

ハッシュアルゴリズムはITインフラの根幹を支える重要技術です。しかし「どのハッシュを何に使うか」は用途によって明確に分かれます。データ整合性や署名にはSHA-2/3やBLAKE2/3、パスワード保存にはArgon2などのメモリハードKDFを用いること、MD5やSHA-1のような既に破られたアルゴリズムは使わないことが現在の常識です。さらに、実装は信頼できるライブラリに任せ、プロトコル全体で脅威モデルを考慮することが重要です。

参考文献