ハッシュ値の実務・応用
ここでは「ハッシュを実務で安全に使うための注意点とコツ」をまとめます。衝突リスクの感覚、チェックサムとの違い、HMAC/署名/KDFの役割分担、表記揺れや正規化の罠を押さえておきましょう。
🧭 このページで扱うこと
概要
- ✅ 衝突リスクの目安と短縮ハッシュの注意点
- ✅ チェックサム(CRCなど)との違いと使い分け
- ✅ HMAC / デジタル署名 / パスワードハッシュ(KDF)の役割分担
- ✅ 表記揺れ(hex/BASE64)や入力正規化の落とし穴
- ✅ 大容量向けストリーミングハッシュとコンテンツアドレスの実例
⚠️ 衝突リスクと短縮ハッシュ
以下は独立で一様なNビット値を集めたとき、1組以上の衝突が起きる確率が約50%になる件数です。実際の弱いアルゴリズムへの攻撃コストではありません。
ビット長と目安
| ビット数 | 約50%となる件数 |
|---|---|
| 64 | 5.06 × 10^9 |
| 128 | 2.17 × 10^19 |
| 160 | 1.42 × 10^24 |
| 256 | 4.01 × 10^38 |
短縮時の注意
- ✂️ 近似式は n ≈ √(2 ln 2) × 2^(N/2)。出力を短縮すると、偶然の衝突だけでなく衝突探索への強度も下がる。
- ✂️ 識別子を短く表示する場合も元の値を保持し、衝突が起きた場合の扱いを決める。
- ✂️ 衝突探索と、指定されたハッシュに一致する入力を探す原像探索は別の問題。ハッシュは公開鍵でも暗号化でもない。
🧮 チェックサムとの違い
CRC/Adlerなどはエラー検出向けで、改ざん耐性は弱いです。
使い分け
- 🔍 CRCなどは偶発的な破損の検出に使う。攻撃者の偽造への対策にはしない。
- 🔍 SHA-256で照合するときも、期待値を信頼できる経路で入手する。ファイルと期待値が両方差し替えられるなら一致だけでは防げない。
- 🔍 認証にはHMACや信頼する鍵の電子署名など、用途に合う仕組みを使う。
🧰 HMAC / 署名 / パスワードハッシュ
「誰が秘密を持ち、何を守りたいか」で選びます。
役割分担
- 🧠 HMACは共有秘密鍵による認証。鍵を持つ全員が生成でき、内容は暗号化しない。
- 🧠 電子署名は信頼する公開鍵で検証する。正規化はプロトコルが定めた場合だけ、その規則に従って行う。
- 🧠 パスワードはソルト付きの専用ライブラリで保存する。Argon2idやscryptはメモリコストも設定できる。PBKDF2は反復回数による計算コストであり、これらをすべてメモリハード方式と呼ばない。
移行と運用のコツ
- 🔧 ハッシュ方式を変える場合、ログイン成功時に新方式へ再ハッシュする「段階移行」が実践的。
- 🔧 ペッパー(アプリ側共有の秘密値)を追加すると漏洩耐性が向上するが、ローテーション設計が必要。
🧾 表記揺れと正規化の罠
入力バイト列の変更と、同じハッシュ値の表示方法の変更を区別します。
よくある揺れ
- 📌 hexの大文字/小文字、`0x` の有無、区切り文字で異なる文字列になる。
- 📌 Base64とBase64urlで文字列が違っても、正しく復号すれば同じダイジェストのバイト列を表せる。表記と値を混同しない。
- 📌 入力データの改行コード(LF/CRLF)やUnicode正規化(NFC/NFD)で別ハッシュになる。
対策
- 🛠️ 正規化するのは仕様で合意した場合だけ。配布ファイルをそのまま検証する場合や署名対象のバイト列を、独自に変換しない。
- 🛠️ 外部から受け取るハッシュ値はエンコード方式(hex/BASE64URLなど)を合わせる。
⏩ ストリーミングハッシュとコマンド例
同じハッシュ計算の状態に、順番どおり小分けに入力すれば、全体を一度に入力した場合と同じ値になります。断片ごとのハッシュを並べる方法とは異なります。
実務のポイント
- 🚚 PHPのhash_updateでは同じコンテキストを更新し、最後にhash_finalする。
- 🚚 複数ファイルの一覧は、ファイル名・アルゴリズム・期待値を明示し、一覧自体も信頼できる経路で届ける。
- 🚚 部分検証には、信頼できる断片別の期待値や検証用の木構造などを別途設計する。全体ハッシュだけから部分の正しさは検証できない。
📦 コンテンツアドレスの実例
「中身で参照する」仕組みは再現性とキャッシュ効率を上げます。
例
- 🧱 GitのオブジェクトIDはヘッダーと内容を対象にするため、ファイル内容だけのSHA-256とは異なる。SHA-1/SHA-256はリポジトリの形式による。
- 🧱 IPFSのCIDにはハッシュに加えて形式などの情報がある。ファイルの分割やDAG構成にも依存し、単純なファイル全体のハッシュとは限らない。
❓ よくある質問
Q. MD5やSHA-1をまだ使っていい?
- A. 衝突耐性が必要な用途では不可。レガシー互換か非安全用途のみに限定し、置き換えを計画する。
Q. 何bitあれば安全?
- ハッシュのビット数を増やしても内容は秘密にならない。秘匿には暗号化が必要。衝突耐性・原像耐性・プロトコル要件を区別して方式と長さを選ぶ。