ゆるテックノート

ハッシュ値の実務・応用

ここでは「ハッシュを実務で安全に使うための注意点とコツ」をまとめます。衝突リスクの感覚、チェックサムとの違い、HMAC/署名/KDFの役割分担、表記揺れや正規化の罠を押さえておきましょう。

🧭 このページで扱うこと

概要

  • 衝突リスクの目安と短縮ハッシュの注意点
  • チェックサム(CRCなど)との違いと使い分け
  • HMAC / デジタル署名 / パスワードハッシュ(KDF)の役割分担
  • 表記揺れ(hex/BASE64)や入力正規化の落とし穴
  • 大容量向けストリーミングハッシュとコンテンツアドレスの実例

⚠️ 衝突リスクと短縮ハッシュ

短くすると衝突確率が上がるため、用途に応じてビット長を選びます。

ビット長と目安

ビット長 Birthday boundの目安 主な用途の目安
64bit 約 5e9 個で衝突が現実的 一時的なIDや短縮ハッシュ(長期保管は非推奨)
128bit 約 3e19 個 MD5は衝突攻撃が実用。安全用途は不可。
160bit 約 1e24 個 SHA-1は攻撃が現実的。安全用途は不可。
256bit 約 1e38 個 SHA-256以降が一般的な安全用途。

短縮時の注意

  • ✂️ ハッシュを先頭Nビットに切ると、衝突確率は `2^(N/2)` 付近で現実的になる(Birthday bound)。
  • ✂️ URLキーやUI表示で短縮する場合、元の値も保持するか、十分なビット長を残す。
  • ✂️ 「安全」かどうかは攻撃コスト次第。公開キーに使うならSHA-256以上を選ぶ。

🧮 チェックサムとの違い

CRC/Adlerなどはエラー検出向けで、改ざん耐性は弱いです。

使い分け

  • 🔍 配送・転送の整合性チェック → CRC32/Adler32で十分な場面もある。
  • 🔍 改ざん検知・署名・認証 → SHA-256 などの暗号学的ハッシュが必須。
  • 🔍 配布ファイルの検証リンクは SHA-256 以上を添えると安心。

🧰 HMAC / 署名 / パスワードハッシュ

「誰が秘密を持ち、何を守りたいか」で選びます。

役割分担

  • 🧠 HMAC: 共有鍵がある前提で改ざん検知。鍵が漏れると偽造可能。
  • 🧠 デジタル署名: 公開鍵で検証。非公開鍵の管理が重要。署名前に正規化が必要なプロトコルも多い(XML/JSON)。
  • 🧠 パスワードハッシュ(KDF): PBKDF2/bcrypt/scrypt/Argon2 などでストレッチ&メモリハード化し、ソルトを必須にする。

移行と運用のコツ

  • 🔧 ハッシュ方式を変える場合、ログイン成功時に新方式へ再ハッシュする「段階移行」が実践的。
  • 🔧 ペッパー(アプリ側共有の秘密値)を追加すると漏洩耐性が向上するが、ローテーション設計が必要。

🧾 表記揺れと正規化の罠

同じ値でも表現や入力の揺れで別ハッシュになることがあります。

よくある揺れ

  • 📌 hexの大文字/小文字、`0x` の有無、区切り文字で異なる文字列になる。
  • 📌 BASE64 と BASE64URL、改行あり/なしで値が変わる(メール系ツールに注意)。
  • 📌 入力データの改行コード(LF/CRLF)やUnicode正規化(NFC/NFD)で別ハッシュになる。

対策

  • 🛠️ ハッシュする前に入力を正規化し、方針を仕様書に明記する。
  • 🛠️ 外部から受け取るハッシュ値はエンコード方式(hex/BASE64URLなど)を合わせる。

ストリーミングハッシュとコマンド例

大きなファイルは分割してハッシュし、メモリ消費を抑えます。

実務のポイント

  • 🚚 `hash_update` / `hash_file`(PHP)や `openssl dgst -sha256 file` でストリーミング可能。
  • 🚚 複数ファイルをまとめて検証する場合、マニフェスト(ファイル名+ハッシュ一覧)を作る。
  • 🚚 一部のみ検証したい場合は範囲ハッシュを使う設計もある(大容量ストレージの検査など)。

📦 コンテンツアドレスの実例

「中身で参照する」仕組みは再現性とキャッシュ効率を上げます。

  • 🧱 GitのオブジェクトID(SHA-1→SHA-256移行中)
  • 🧱 IPFS/CASのコンテンツID(Base58/BASE32表記のハッシュ)
  • 🧱 Dockerイメージのレイヤーダイジェスト(SHA-256)

よくある質問

Q. MD5やSHA-1をまだ使っていい?

  • A. 衝突耐性が必要な用途では不可。レガシー互換か非安全用途のみに限定し、置き換えを計画する。

Q. 何bitあれば安全?

  • A. 現行で一般的なのはSHA-256(256bit)。長期秘匿が必要ならSHA-512系などで余裕を取る。