MD5 vs SHA-256 — MD5 の使用をやめるべき理由
MD5 はあらゆる場所にあります。すべてのプログラミング言語、すべてのデータベース、すべてのクラウドプロバイダの SDK に出荷されます。開発者は習慣でそれに手を伸ばします — 高速で、きれいな 32 文字の 16 進文字列を生成し、API は 2 行のコードです。問題: MD5 は 2004 年から暗号的に破られており、攻撃はそれ以来速くなり安くなるばかりです。
これは理論ではありません。2012 年のイランのインフラに対するサイバー攻撃 — Flame マルウェア — は、MD5 衝突を悪用して Microsoft のコード署名証明書を偽造しました。学術暗号学者が論文で実証した同じ技術が、地政学的スパイ活動で使用される武器になりました。MD5 はわずかに弱まっているのではありません。敵が入力を選択できる任意のアプリケーションに対して根本的に侵害されています。
NIST によって標準化された SHA-2 ファミリーの一部である SHA-256 には既知の衝突攻撃がなく、2026 年の暗号整合性の標準のままです。この記事では、違いが正確に何を意味するか、いつ (まれに) MD5 が依然として許容されるか、そして安全に移行する方法を説明します。Toova MD5 hash と Toova SHA-256 hash ツールで両方のハッシュを即座に計算できます。
ハッシュ関数の動作
暗号ハッシュ関数は、任意の長さの入力を取り、これらの特性を持つ固定長の出力 (ダイジェスト) を生成します:
- 決定論的: 同じ入力は常に同じ出力を生成します。
- アバランシェ効果: 入力で 1 ビットを変更すると出力が完全に変わります。
- 原像耐性: ハッシュが与えられた場合、入力を見つけることが計算的に不可能です。
- 衝突耐性: 同じハッシュを生成する 2 つの異なる入力を見つけることが計算的に不可能です。
アバランシェ効果は、MD5 と SHA-256 が一目で似て見える理由です:
MD5("The quick brown fox jumps over the lazy dog")
= 9e107d9d372bb6826bd81d3542a419d6
MD5("The quick brown fox jumps over the lazy cog")
= 1055d3e698d289f2af8663725127bd4b SHA-256("The quick brown fox jumps over the lazy dog")
= d7a8fbb307d7809469ca9abcb0082e4f8d5651e46d3cdb762d02d0bf37c9e592
SHA-256("The quick brown fox jumps over the lazy cog")
= e4c4d8f3bf76b692de791a173e05321150f7a345b46484fe427f6acc7ecc81be 入力で 1 文字が変更されました ("dog" → "cog") が、出力は完全に異なります。この特性は両方のアルゴリズムに当てはまります。違いは、攻撃者が意図的に衝突を見つけようとするときに起こることです。
MD5 — 失敗のタイムライン (1996–2025)
MD5 は、MD4 の代替として 1991 年に Ron Rivest によって設計されました。1996 年までに、Hans Dobbertin は MD5 の圧縮関数に衝突を見つけました — 完全なアルゴリズムではありませんが、設計が脆弱であるという警告サインです。セキュリティコミュニティは SHA-1 への移行を推奨し始めました。ほとんどのシステムはこれを無視しました。
2004 — 完全な衝突が実証される
2004 年 8 月、Xiaoyun Wang と Hongbo Yu は CRYPTO カンファレンスで MD5 に対する実用的な衝突攻撃を発表しました。彼らはクラスター上で 1 時間未満で同じ MD5 ハッシュを持つ 2 つの異なる 1,024 ビットメッセージを生成できました。MD5 の基本的な保証 — 衝突耐性 — が破られました。
NIST は連邦使用のために MD5 をすぐに非推奨にし始めました。ほとんどの業界ガイダンスがそれに従いました。本番システムでの MD5 の実際の展開はほとんど変わりませんでした。
2008 — 不正な CA 証明書
研究者のグループ (Sotirov、Stevens など) は、すべての主要ブラウザによって信頼される不正な認証局証明書を作成できることを実証しました。攻撃は、いくつかの認証局が依然として MD5 で証明書に署名しているという事実を悪用しました。研究者は、合法的に見える証明書要求と自己作成された CA 証明書の間に衝突を生成し、その後、本物の CA に合法的なものに署名してもらい、偽造された CA 証明書にも有効な署名を生成しました。
すべての主要ブラウザがすぐに MD5 で署名された証明書をブロックしました。ほとんどの認証局がそれらの発行を停止しました。1 つの主要な教訓: 暗号的弱点は、攻撃者がハッシュ関数への入力を制御した瞬間に悪用可能になります。
2012 — Flame マルウェア
2012 年に発見され、国家アクターに帰属するとされる Flame サイバースパイマルウェアは、選択プレフィックス MD5 衝突を使って Microsoft Windows Update 証明書を偽造しました。攻撃は 2008 年のデモよりも洗練されていました: 攻撃者は、Microsoft の署名インフラが知らずに協力する条件下で、合法的な Microsoft 証明書と衝突する悪意のあるペイロードを作成できました。
結果: Flame は、有効な Microsoft 署名を持つ合法的な Microsoft アップデートのように、Windows Update を通じて自分自身を配布できました。イラン、レバノン、シリア、スーダンの数十万の Windows マシンが感染しました。これは、国家レベルでの MD5 衝突攻撃の現実世界での悪用でした。完全な歴史については、Flame マルウェアに関する Wikipedia の記事を参照してください。
2019–2025 — HashClash と即時衝突
HashClash プロジェクト (Marc Stevens、CWI Amsterdam) は MD5 衝突生成を実用的な限界まで押し続けました。2019 年までに、選択プレフィックス MD5 衝突 — 攻撃者が両方の衝突するメッセージに任意のプレフィックスを選択できる — は、コモディティハードウェアで数日で生成できました。2022 年までに、最適化された実装でこれは数時間に減少しました。2024 年、HashClash の論文は、単一の現代の GPU で 1 分未満で衝突を実証しました。
軌跡は明確です: MD5 衝突攻撃はハードウェアが改善するにつれて難しくならず — 容易になっています。2004 年にクラスターが必要だったものが、2026 年にはラップトップでできます。
SHA-256 — なぜそれは持ちこたえるのか
SHA-256 は NSA によって設計され、2001 年に NIST によって標準化された SHA-2 ファミリーの一部です。256 ビット (32 バイト) のダイジェストを生成します。2026 年現在、SHA-256 に対する実用的な衝突攻撃は知られていません。公開された最良の攻撃は、衝突を見つけるための理論的な作業係数を約 2^187 演算に減らします — 存在する、または予見可能などの計算リソースをもはるかに超えています。
SHA-256 のセキュリティマージンは意図的に保守的です。ハードウェアが 10 億倍 (ムーアの法則の用語でおよそ 30 倍化) 改善しても、SHA-256 を破ることは計算的に不可能のままです。2004 年に衝突のための MD5 の 2^18 から 2^23 の有効な作業係数は、わずかなハードウェアの範囲内でした。
SHA-256 は期待よりも高速です: 現代の CPU には、コアごとに毎秒数百万の SHA-256 ハッシュを計算できる専用の SHA 命令 (Intel SHA Extensions、ARM Cryptography Extensions) が含まれています。典型的なユースケースでは MD5 より意味のあるほど遅くはありません。
MD5 がまだ許容される場合 (まれ)
「破られている」は「すべての目的に役に立たない」を意味しません。MD5 は次のコンテキストで依然として許容されます:
- 敵がいない: 信頼できる内部システムでの偶発的なファイル破損の検出 — インターネットからのダウンロードの検証ではなく、ファイルコピーが正常に完了したかどうかのチェック。
- セキュリティよりも速度が重要: 衝突が単にキャッシュミスを意味し、セキュリティ違反ではない、キャッシュキーやシャード識別子の計算。攻撃者モデルが不在です。
- 既存の外部システムに合わせる: 一部のレガシー API は依然として MD5 ETag やチェックサムを送信します。セキュリティの決定にそれを使用していない限り、相互運用するために MD5 を受け入れて計算できます。
- ハッシュテーブルパーティショニング: キーの MD5 でバケットにデータを分散。ここでの衝突はセキュリティ障害ではなく不均衡を引き起こします。
共通の糸: MD5 は、アプリケーションが衝突耐性に依存せず、入力を作成できる敵がいないときに許容されます。いずれかの条件が破れる — 攻撃者が存在する、または衝突 = セキュリティ障害 — とすぐに、SHA-256 に切り替えてください。
MD5 に関するよくある神話
「ソルトを追加すれば MD5 は問題ない」
ソルティングは、同じパスワードを持つ 2 人のユーザーが異なるハッシュを取得するように入力を変更します — レインボーテーブル攻撃を防ぎます。しかし、衝突問題は修正されません。ソルトされた MD5 ハッシュを持つ攻撃者は、MD5 が高速であるため、依然として効率的にブルートフォースできます: 現代の GPU は毎秒約 100〜300 億の MD5 ハッシュを計算します。ソルトはアルゴリズムの難しさではなく、検索空間に比例する作業を追加します。
パスワードハッシュには、ソルティングに関係なく MD5 も SHA-256 も適切ではありません。bcrypt、scrypt、または Argon2 を使用してください。
「内部でのみ使用するので MD5 は問題ない」
内部システムは侵害されます。脅威モデル「攻撃者は入力にアクセスできない」は、サプライチェーン攻撃、内部脅威、または誤設定がシステムを露出させるまで持ちこたえる傾向があります。Flame 攻撃は、おそらく内部制御に同様の信頼を持っていたシステムに対して発生しました。
「SHA-256 は過剰 — MD5 のほうが速い」
SHA 加速命令を持つ現代のハードウェアでは、SHA-256 は MD5 より約 2〜5 倍遅いです。ほとんどのアプリケーション — ファイル整合性チェック、API 署名、キャッシュキー — では、違いは演算ごとにマイクロ秒であり、実際には気づかれません。SHA-256 に対する MD5 のパフォーマンス引数は、マイクロ秒さえ重要な極めて高スループットのシナリオでのみ成り立ち、それでも通常、破られたアルゴリズムを使うよりも良い解決策があります。
移行ガイド — MD5 から SHA-256
パスワードハッシュ
// 間違い: パスワードハッシュに MD5
const crypto = require('crypto');
const hash = crypto.createHash('md5').update(password).digest('hex');
// 現代の GPU でのクラック時間: 数秒から数分 // 間違い: パスワードハッシュに SHA-256 (依然として速すぎる)
const crypto = require('crypto');
const hash = crypto.createHash('sha256').update(password).digest('hex');
// 正しい: パスワードには bcrypt、scrypt、または Argon2 を使用
const bcrypt = require('bcrypt');
const hash = await bcrypt.hash(password, 12); 保存されたパスワードハッシュの移行には、段階的なアプローチが必要です。各成功したログインで: 既存の MD5 ハッシュに対してパスワードを検証し、即座に bcrypt で再ハッシュし、保存された値を置き換えます。各アカウントを移行済みとしてフラグ付けします。妥当な期間 (90 日が一般的) の後、依然として MD5 ハッシュを使用している残りのアカウントに対してパスワードリセットを強制します。
ファイル整合性 / チェックサム
# Linux: ファイルダウンロードを検証
sha256sum -c ubuntu-24.04-desktop-amd64.iso.sha256
# macOS
shasum -a 256 ubuntu-24.04-desktop-amd64.iso
# Windows PowerShell
Get-FileHash ubuntu-24.04-desktop-amd64.iso -Algorithm SHA256 ファイル整合性チェックを MD5 から SHA-256 に切り替えるのは、通常コードでの単純な検索と置換です。2 つの落とし穴: (1) データベースやファイルに保存された既存のチェックサムは再計算および更新が必要です — ショートカットはありません; (2) MD5 ETag を提供する外部 API や保存システム (一部の S3 設定など) は、切り替えに調整が必要です。
API 認証用 HMAC
// メッセージ認証用 HMAC-SHA-256
const crypto = require('crypto');
const hmac = crypto.createHmac('sha256', process.env.SECRET_KEY)
.update(message)
.digest('hex'); API リクエスト署名に HMAC-MD5 を使用している場合、HMAC-SHA-256 に切り替えてください。HMAC 構造は秘密鍵を追加し、いくつかの MD5 攻撃を制限しますが、HMAC-MD5 には長さ拡張の脆弱性があり、根底にある原始機能は依然として侵害されています。現代の標準 (JWT、AWS SigV4、OAuth 2.0) はすべて HMAC-SHA-256 を指定します。Toova の HMAC ジェネレーターはテスト用に HMAC-SHA-256 と HMAC-SHA-512 の両方をサポートします。
デジタル署名と証明書
MD5 で署名された任意の証明書は、すぐに再発行する必要があります — ほとんどの認証局は 2008 年以降 MD5 で署名された証明書の発行を停止し、すべての主要なブラウザとオペレーティングシステムはそれらを拒否します。内部 PKI には、CA 設定を監査し、SHA-256 が許可される最小の署名アルゴリズムであることを確認します。RSA-SHA256 または ECDSA-SHA256 が現在の標準です。
MD5 vs SHA-256 — クイックリファレンス
| 特性 | MD5 | SHA-256 |
|---|---|---|
| 出力長 | 128 ビット (32 16 進文字) | 256 ビット (64 16 進文字) |
| 衝突耐性 | 破られている (実用的攻撃) | 安全 (既知の攻撃なし) |
| パスワードハッシュ | 絶対に使わない | 使わない (bcrypt/Argon2 を使用) |
| デジタル署名 | 絶対に使わない | 使う |
| ファイル整合性 (セキュリティ) | 絶対に使わない | 使う |
| 非セキュリティチェックサム | 許容 (攻撃者なし) | 常に問題なし |
| キャッシュキー | 許容 | 常に問題なし |
| TLS 証明書署名 | ブラウザによって拒否 | 標準 |
| FIPS 140-3 準拠 | いいえ (非推奨) | はい |
結論
MD5 は 2004 年から暗号的に破られています。選択プレフィックス衝突 — Flame マルウェアを動かした技術 — は今や計算的に安価です。セキュリティ (署名、整合性検証、認証) のために MD5 に依存するアプリケーションは、実行に数分の計算時間がかかる攻撃に対して脆弱です。
SHA-256 には既知の実用的な攻撃はなく、現代の CPU でハードウェアアクセラレーションされており、TLS、コード署名、API 認証にわたって暗号整合性の標準です。MD5 と比較したパフォーマンスコストは、ほぼすべてのユースケースで無視できるほどです。
移行パスは簡単です: ファイル整合性チェックは検索と置換です。API 署名はバージョン更新の調整が必要です。パスワードハッシュにはログイン時の段階的な再ハッシュ戦略が必要です。新しいコードには、SHA-256 がデフォルトの選択肢であるべきです。Toova MD5 と Toova SHA-256 でハッシュを直接計算および比較したり、HMAC ジェネレーターで HMAC-SHA-256 認証コードを生成したりしてください。