暗号学的ハッシュ関数(Cryptographic Hash Function)
1. 概要
定義: 暗号学的ハッシュ関数(Cryptographic Hash Function)とは、任意長の入力メッセージを固定長の要約値(ハッシュ値・ダイジェスト)へ写像しつつ、原像・第二原像・衝突を計算的に見つけにくいよう設計された一方向関数である。
情報システムでは「データが転送・保存中に変わっていないか」「このユーザが提示したパスワードは登録されたものと同じか」「この文書は署名当時のその文書で間違いないか」という問いが絶えず発生する。これらの問いはすべて、原本全体を再比較せずとも短い指紋(fingerprint)一つで同一性を判定できて初めて実用的である。暗号学的ハッシュ関数はまさにこの指紋を生成する基本プリミティブであり、電子署名・メッセージ認証・完全性検証・パスワード保存・ブロックチェーン・重複排除まで現代セキュリティのほぼ全層に浸透している。
単純なチェックサム(CRC、パリティ)も固定長の要約値を作るが、これらは偶発的な誤りの検出のみを目的とするため、攻撃者が意図的に同じ値を持つ別のデータを作り出せる。一方で暗号学的ハッシュは、攻撃者が計算資源を注ぎ込んでも望む要約値を満たす入力を見つけにくいという意図的な偽造防止を核心要件とする。この違いが「ハッシュ」という同じ語の下にまったく異なる保証水準を生む。
暗号学的ハッシュが重要なのは、それが信頼の圧縮を可能にするからである。数ギガバイトのディスクイメージ、数百万件のトランザクション、任意長の証明書チェーンを256ビットの値一つに要約し、その値だけを安全なチャネルで伝えれば、残りの膨大なデータは信頼できない経路で運んでも改ざんを検出できる。例えばLinuxディストリビューションは数GBのISOファイルに対しSHA-256値一つ(64桁の16進数)だけを公式サイトに掲載し、利用者はミラーサーバから受け取ったファイルを自ら計算して照合する。1,000万件のデータを比較する問題が32バイトの比較問題に変わるのである。
登場背景と必要性
初期の暗号学は機密性(暗号化)に集中したが、ネットワークが拡散するにつれ「内容を隠すこと」よりも「内容が変わっていないこと」と「送信者が本物であること」を証明する完全性・認証の需要が急増した。公開鍵署名はメッセージ全体ではなくそのハッシュ値に署名することで署名コストを定数化し、これによりハッシュは署名方式の必須の前処理段階となった。
またパスワードを平文で保存すると、データベース漏洩時に全アカウントが即座に奪取されるため、パスワードは復元不可能な形で保管しなければならない。一方向性を持つハッシュは「保存はするが元には戻せない」保存方式を提供し、パスワード保護の標準手段となった。後述するように汎用ハッシュをそのまま使うのは危険であり、専用のパスワードハッシュが必要だという点が重要な深掘りポイントである。
技術士の観点での問題定義
論述答案では、ハッシュ関数を「固定長に縮める関数」としてのみ記述すれば失敗である。核心は、三つのセキュリティ性質(原像・第二原像・衝突耐性)と、それぞれが破られたときに崩れる応用を結び付け、誕生日逆説によるセキュリティ強度の半減、Merkle–Damgård構造の長さ拡張脆弱性、汎用ハッシュとパスワードハッシュの目的の違いを区別して説明することである。すなわち「どの応用にどの性質がなぜ必要か」を軸とすべきである。
2. 核心的なセキュリティ性質と要求特性
暗号学的ハッシュ関数Hが安全であると言うには、三つの計算的困難性を満たさなければならない。下の構造図は入力・処理・出力の流れと、各性質が防御する攻撃を併せて示す。
flowchart TD
M["任意長メッセージ M"] --> P["パディング + ブロック分割"]
P --> C["圧縮/吸収過程(ラウンド反復)"]
C --> D["固定長ダイジェスト H(M)"]
D --> U1["完全性検証(ファイル/ファームウェア)"]
D --> U2["電子署名の前処理"]
D --> U3["パスワード保存"]
D --> U4["ブロックチェーン/マークルルート"]
A1["原像攻撃: H(M)からMを復元"] -. 防御 .-> C
A2["第二原像: 同じハッシュの別のMを探す"] -. 防御 .-> C
A3["衝突: H(M1)=H(M2)となる任意の対"] -. 防御 .-> C
A. 原像耐性(Preimage Resistance)
原像耐性とは、与えられたハッシュ値yに対しH(M)=yとなる入力Mを見つけにくくあるべきという性質で、しばしば一方向性(one-wayness)と呼ぶ。パスワード保存がこの性質に依存する。データベースに保存されたダイジェストだけでは元のパスワードを復元できないことで、攻撃者が漏洩したハッシュでログインできない。
理想的なハッシュの原像攻撃コストはnビット出力に対し約2^n回の試行である。したがってSHA-256は原像攻撃に約2^256のコストを要し、これは現存・近未来の演算力では不可能な水準である。しかしパスワードのように入力空間自体が小さければ(人が使うパスワードのエントロピーは通常20〜40ビット)、ハッシュの理論的強度と無関係に総当たり(brute-force)で破られる。この点が「強いハッシュを使っても弱いパスワードは守れない」という実務上の教訓の根拠である。
実務では原像耐性を過信し、機微な識別子(住民番号、メール)を塩なしでハッシュして保存する事例がよくあるが、値の分布が狭ければ事前計算されたテーブルで逆追跡されるため、事実上一方向性が破られる。すなわち原像耐性は入力分布とともに評価すべき条件付きの性質である。
B. 第二原像耐性と衝突耐性
第二原像耐性(Second Preimage Resistance)は、特定のメッセージMが与えられたとき同じハッシュを持つ別のM'を見つけにくくあるべきという性質である。一方で衝突耐性(Collision Resistance)は、攻撃者が自由にH(M1)=H(M2)となる任意の対を見つけにくくあるべきという、より強い要求である。
二つの性質の違いは攻撃コストで極めて際立つ。第二原像は2^nに近いが、衝突は誕生日逆説(birthday paradox)により約2^(n/2)へ急減する。23人集まるだけで誕生日が重なる確率が50%を超える直観のように、無作為な値を約2^(n/2)個集めれば二つが重なる可能性が高まる。そのため128ビットのセキュリティ強度を目標とするなら、ハッシュ出力は少なくとも256ビットでなければならない。SHA-256が「128ビット級の衝突耐性」と評価される理由がここにある。
衝突耐性が最も致命的に要求される場は電子署名である。攻撃者が「善意の契約書」と「悪意の契約書」が同じハッシュを持つように作れれば、被害者が前者に署名した署名値が後者にもそのまま有効になる。実際に2012年のFlameマルウェアはMD5衝突を悪用して偽造されたコード署名証明書を作り、Windows Updateを通じて伝播したが、これは衝突耐性の喪失がどのように全地球的な攻撃へつながるかを示した代表的な事例である。
C. なだれ効果と決定性・効率性
良いハッシュは入力が1ビット変わるだけで出力の約半分のビットが予測不能に反転するなだれ効果(avalanche effect)を示す。これは入力と出力の統計的相関を除去し、攻撃者が部分情報を推論できないようにする。同時にハッシュは決定的(deterministic)であり、同じ入力は常に同じ値を出さねばならず(検証可能性の前提)、大量データにも適用できるよう計算効率が良い必要がある。
興味深い緊張関係がここにある。完全性・署名用のハッシュは速いほど良いが、パスワード用のハッシュはむしろ意図的に遅くあるべきで、攻撃者の総当たりを難しくする。同じ「ハッシュ」でも目的によって設計目標が正反対なのである。この緊張を認識せずSHA-256でパスワードを保存すると、GPUで毎秒数十億回のハッシュが可能なため、漏洩時の防御力がほとんどない。
3. 代表的なアルゴリズムと内部構造
ハッシュの内部構造は大きくMerkle–Damgård(MD)構造とスポンジ(sponge)構造に分かれる。下の詳細プロセス図は二つの構造の処理フローの違いを表す。
flowchart LR
subgraph MD["Merkle-Damgard構造(MD5/SHA-1/SHA-2)"]
direction LR
IV["初期値 IV"] --> F1["圧縮関数 f(ブロック1)"]
F1 --> F2["圧縮関数 f(ブロック2)"]
F2 --> F3["圧縮関数 f(ブロックn)"]
F3 --> OUT1["最終チェイニング値 = ダイジェスト"]
end
subgraph SP["スポンジ構造(SHA-3/Keccak)"]
direction LR
S0["状態の初期化"] --> AB["吸収(absorb): メッセージをXOR後に順列 f"]
AB --> SQ["圧出(squeeze): 状態から出力を抽出"]
SQ --> OUT2["可変長ダイジェスト"]
end
A. 世代別アルゴリズムの変遷
ハッシュアルゴリズムは攻撃手法の発展に追われながら世代交代を繰り返した。MD5(128ビット)とSHA-1(160ビット)は長らく事実上の標準であったが衝突が実証されてセキュリティ用途から退場し、現在はSHA-2系が主力でSHA-3が構造的多様性のための代替として標準化された。下の表は主要なアルゴリズムを比較する。
| アルゴリズム | 出力長(ビット) | 内部構造 | 衝突耐性(ビット) | 状態 |
|---|---|---|---|---|
| MD5 | 128 | Merkle–Damgård | 事実上0(数秒内に衝突) | 廃止 |
| SHA-1 | 160 | Merkle–Damgård | 破られた(≈2^63以下) | 廃止 |
| SHA-256 | 256 | Merkle–Damgård | 128 | 推奨 |
| SHA-512 | 512 | Merkle–Damgård | 256 | 推奨 |
| SHA-3-256 | 256 | スポンジ(Keccak) | 128 | 推奨 |
| SHAKE128/256 | 可変 | スポンジ(XOF) | 128/256 | 推奨 |
B. Merkle–Damgård構造と長さ拡張脆弱性
MD構造はメッセージを固定サイズのブロックに分け、圧縮関数fを鎖のように反復適用し、前のブロックの出力(チェイニング値)を次のブロックの入力へ渡す。実装が単純で、衝突耐性を圧縮関数の安全性へ還元して証明できるという利点で広く使われた。
しかしこの構造には長さ拡張攻撃(length-extension attack)という固有の弱点がある。攻撃者がH(secret || M)の値とメッセージ長だけを知れば、秘密値secretを知らずともH(secret || M || padding || M')を計算できる。このため「ハッシュ(秘密||メッセージ)」をメッセージ認証にそのまま使うと偽造が可能であり、これを防ぐためにHMACという二重ハッシュ構造(H(key⊕opad || H(key⊕ipad || M)))が標準として定着した。SHA-512を切り詰めて使うSHA-512/256やスポンジ構造のSHA-3が長さ拡張に免疫である点も、アルゴリズム選択の重要な考慮事項である。
C. スポンジ構造とSHA-3の意義
SHA-3(Keccak)はNISTが2007〜2012年の公開競技を経て2015年にFIPS 202として標準化したアルゴリズムで、SHA-2と構造そのものが異なる点が核心的な価値である。もし将来SHA-2のMD構造を狙った突破が出ても、まったく異なるスポンジ構造のSHA-3が即座に代替として存在するよう、暗号俊敏性(crypto-agility)の保険を用意したのである。
スポンジ構造は大きな内部状態へメッセージをXORで吸収(absorb)した後に順列を適用し、必要なだけ出力を取り出す(squeeze)方式のため、可変長出力(XOF: SHAKE128/256)を自然に支える。この可変出力の特性はポスト量子署名(SPHINCS+)や鍵導出で柔軟に活用される。
4. 主要な活用とパスワード保存
ハッシュの応用は要求される性質で分類すると理解しやすい。完全性検証(ファイル・ファームウェアのハッシュ照合)は第二原像耐性に、電子署名と証明書は衝突耐性に、メッセージ認証(HMAC)は擬似乱数性に、ブロックチェーンの作業証明とマークルルートは原像・衝突耐性にそれぞれ依存する。データ重複排除(dedup)とコンテンツアドレス指定保存(content-addressable storage)も「内容が同じならハッシュが同じ」という性質をアドレスとする。
A. パスワード保存: 塩・胡椒・鍵ストレッチング
パスワード保存は汎用ハッシュをそのまま使ってはいけない代表的領域である。第一に、同じパスワードが同じハッシュになれば、攻撃者が事前計算したレインボーテーブル(rainbow table)で大量に逆追跡できる。これを防ぐ仕掛けが利用者ごとに異なる無作為な塩(salt)で、塩をハッシュ入力に混ぜれば同一パスワードも互いに異なるダイジェストになり、事前計算攻撃が無力化される。第二に、SHA-256のような速いハッシュはGPUで毎秒数十億回試行されるため、意図的に遅くする鍵ストレッチング(key stretching)が必要である。
この要求を満たすよう専用のパスワードハッシュが発展した。PBKDF2は反復回数でコストを上げるがGPU・ASICに相対的に弱く、bcryptはBlowfishベースでメモリをわずかに使い、scryptとArgon2はメモリハード(memory-hard)設計で大量並列ハードウェア攻撃のコストを大きく高める。2015年のPassword Hashing Competitionで優勝したArgon2(特にサイドチャネル耐性型のArgon2id)が現在の第一推奨案である。OWASPはArgon2idを約19MiBメモリ・2回反復・並列度1、またはPBKDF2-HMAC-SHA256を約60万回反復で設定するよう案内する。運用組織はさらにサーバのみに保管する秘密値である胡椒(pepper)をHMACの形で結合し、データベースだけが漏洩した場合の防御線をもう一段設ける。
B. 電子署名・証明書におけるハッシュ
電子署名はメッセージ全体ではなくそのダイジェストに署名するため、ハッシュの衝突耐性がそのまま署名の偽造不可能性へ直結する。公認証明書・コード署名・TLS証明書チェーンはすべて署名対象のハッシュアルゴリズムを明示しており、産業界がSHA-1署名証明書を2017年前後に一括廃止したのは、先に見た衝突実証への直接的な対応であった。
5. 比較および攻撃事例
アルゴリズム選択を「出力長が長いほど良い」と単純化すると実務設計を誤る。長さ拡張免疫の有無、ハードウェア加速支援、標準・規制適合性、性能がすべて変数である。下の表は選択時の考慮軸とその理由を整理する。
| 考慮軸 | 核心的な問い | 実務上の含意 |
|---|---|---|
| セキュリティ強度 | 衝突耐性が何ビット必要か | 128ビット級ならSHA-256、長期保存・高価値はSHA-384/512 |
| 構造の多様性 | 長さ拡張に免疫か | 認証にはHMAC、またはSHA-3/SHA-512-256を選択 |
| 目的適合性 | 速いほど良いか遅いほど良いか | 完全性はSHA-2、パスワードはArgon2id |
| 規制適合性 | 国内外の標準承認アルゴリズムか | 国内の電子署名はSHA-256以上、国際はFIPS承認の有無 |
攻撃事例はこの選択の根拠を生き生きと示す。MD5は2004年に王小雲の研究チームが実用的な衝突を発表した後、数秒内に衝突生成が可能になり、2008年には偽造CA証明書が作られた。SHA-1は2017年のGoogleとCWIによるSHAttered攻撃で、約9.2×10^18(約2^63)回の演算で二つの異なるPDFが同じSHA-1ハッシュを持つ実証衝突が公開され、2020年には選択接頭辞衝突のコストが数万ドル水準まで下がった。これらの数値は「理論的に破られた」ことと「現実的に悪用可能な」ことの間の距離が思ったより短いという教訓を与える。
6. 深掘り: 標準の変化とポスト量子時代のハッシュ
暗号学的ハッシュをめぐる最新の争点は量子コンピューティングの脅威と、それに伴う標準の再評価である。公開鍵暗号(RSA・ECC)はショア(Shor)アルゴリズムで多項式時間に破られうるため事実上の全面交換が必要だが、対称鍵・ハッシュはグローバー(Grover)アルゴリズムが原像探索を2^nから2^(n/2)へ平方根水準だけ加速する。したがってSHA-256の原像耐性は量子環境で128ビット級へ下がる程度であり、衝突耐性(すでに128ビット)と合わせ、保守的にはSHA-384/SHA-512への引き上げが推奨される。すなわちハッシュは量子時代にも「廃止」ではなく「出力長の引き上げ」で対応可能な、相対的に堅固なプリミティブである。
逆説的に、ハッシュはポスト量子暗号の解決策でもある。NISTが2024年に標準化したポスト量子署名のうちSPHINCS+(FIPS 205、SLH-DSA)は、格子・符号のような新しい数学的仮定なしにハッシュ関数の安全性だけに依存するハッシュベース署名で、数学的仮定が少なく最も保守的に信頼される。XMSS・LMSのような状態保持ハッシュ署名もファームウェア署名などで採用されている。このようにハッシュは「攻撃される対象」であり「防御の土台」であるという二重の地位を持つ。
標準面ではNIST FIPS 180-4(SHA-1/2)・FIPS 202(SHA-3)が基盤であり、2022年にNISTはSHA-1の完全な使用中止を2030年まで段階的に推進すると公表した。国内でも電子署名・公共システムでSHA-256以上の使用が義務化される趨勢であり、TLS 1.3は脆弱なハッシュ・MACの組み合わせをプロトコル水準で除去して安全なハッシュ使用を強制する。
7. 考慮事項および示唆点
- 暗号俊敏性(crypto-agility)の確保: 特定のハッシュアルゴリズムをコード・データ形式にハードコーディングすると、将来の突破発生時に交換コストが爆増する。アルゴリズム識別子をメタデータとして分離し、複数アルゴリズムを並行支援する設計で、MD5→SHA-1→SHA-256の交換の歴史が繰り返されることを前提とすべきである。
- 目的別アルゴリズム分離の原則: 「一つの良いハッシュ」という幻想を捨て、完全性・署名には速いSHA-2/3を、パスワードには遅いメモリハードのArgon2idを、認証にはHMACを使う用途ベースの選択をガバナンスとして明文化すべきである。パスワードをSHA-256で保存するアンチパターンが依然として多い点が警告である。
- 入力エントロピーと塩・胡椒の結合: ハッシュの理論的強度だけを信じず、低エントロピー入力(パスワード・識別子)には必ず利用者ごとの塩とサーバ側の胡椒、十分な作業係数(work factor)を結合すべきである。作業係数はハードウェアの発展に合わせ定期的に引き上げる運用プロセスが必要である。
- トレードオフと長期保存戦略: 出力長を伸ばせば安全だが保存・転送コストと性能が増加する。長期保存文書・電子記録は署名当時のアルゴリズムが数十年後に脆弱になりうるため、再ハッシュ・再署名(long-term archival signature、例: タイムスタンプトークンの更新)の手順をアーキテクチャに含めるべきである。
- 連携技術と展望: ハッシュはマークルツリー・ブロックチェーン・HMAC・電子署名・KDF・重複排除・コンテンツアドレス指定保存と緊密に絡むため、単一アルゴリズムの交換が上位プロトコルに及ぼす波及を影響分析(impact analysis)で追跡すべきである。量子耐性の観点ではSHA-384以上への引き上げとハッシュベース署名(SPHINCS+)の導入を中期ロードマップへ反映するのが望ましい。
参考資料
- NIST, FIPS 180-4 Secure Hash Standard(SHS), https://doi.org/10.6028/NIST.FIPS.180-4
- NIST, FIPS 202 SHA-3 Standard, https://doi.org/10.6028/NIST.FIPS.202
- NIST, FIPS 205 Stateless Hash-Based Digital Signature Standard(SLH-DSA), https://doi.org/10.6028/NIST.FIPS.205
- OWASP, Password Storage Cheat Sheet, https://cheatsheetseries.owasp.org/cheatsheets/Password_Storage_Cheat_Sheet.html
- Stevens et al., The first collision for full SHA-1(SHAttered), https://shattered.io/
- NIST, Transitioning the Use of Cryptographic Algorithms and Key Lengths(SP 800-131A), https://csrc.nist.gov/pubs/sp/800/131/a/r2/final
一言まとめ: 暗号学的ハッシュ関数は原像・第二原像・衝突耐性を備えた一方向の要約関数であり、誕生日逆説によるセキュリティ強度の半減とMerkle–Damgårdの長さ拡張脆弱性を理解して、完全性・署名・認証にはSHA-2/3とHMACを、パスワードには塩・胡椒とメモリハードのArgon2idを用途別に適用し、量子時代には出力長の引き上げとハッシュベース署名で対応すべき現代セキュリティの中核プリミティブである。