MD5(Message Digest Algorithm 5)は、128ビット(32文字)のハッシュ値を生成する、広く使われている暗号学的ハッシュ関数です。1991年にRonald RivestによってMD4の後継として設計されました。誕生当時、MD5はハッシュ関数設計における大きな前進であり、優れた性能を維持しながら前世代よりも高い安全性を提供しました。その後約20年にわたり、MD5は世界で最も広く使われるハッシュ関数であり、ファイルの完全性検証からデジタル署名まで、さまざまな場面を支えてきました。
しかし、暗号技術の状況は1991年以降、劇的に変化しました。かつて最先端と考えられていたハッシュ関数は、現在では重大な欠陥があることが知られています。MD5の強み、弱み、適切な用途を理解することは重要です。なぜなら、既知の脆弱性にもかかわらず、この関数はいまも広く使われているからです。レガシーシステム、古いソフトウェアのファイルチェックサム、さらには暗号学的な安全性を必要としない一部の現代的な用途でも、MD5ハッシュに遭遇することでしょう。
MD5の仕組み
MD5は任意の長さの入力を受け取り、固定の128ビット出力を生成します。アルゴリズムは入力を512ビットのブロックに分け、4ラウンドの圧縮処理を行います。MD5の内部動作はMerkle-Damgard構造に従っており、これはSHA1やSHA2といった後発のハッシュ関数でも採用されています。
アルゴリズムはまず入力メッセージをパディングし、長さが512を法として448と合同になるようにします(512ビットの倍数より64ビット短い長さです)。パディングは1ビットの1に続けて、必要な長さに達するまでの0ビットで構成されます。パディングの後、元のメッセージ長が64ビット値として追加され、入力全体の長さが512ビットの倍数になります。
各512ビットブロックは4つのラウンドで処理され、各ラウンドには16の操作が含まれます。操作では、現在の状態と入力ブロックを組み合わせる論理関数を使用します。4つのラウンドはそれぞれ異なる論理関数を使用します。F(第1ラウンド)、G(第2ラウンド)、H(第3ラウンド)、I(第4ラウンド)です。これらの関数は、各入力ビットが複雑で非線形な形で出力に影響するように設計されています。
内部状態は4つの32ビットレジスタ(A、B、C、D)で構成され、特定の定数で初期化されます。すべてのブロックを処理した後、これら4つのレジスタの最終値が連結されて128ビットのハッシュ値が生成されます。
アルゴリズムの詳細な手順
MD5アルゴリズムは512ビットのブロックに対して動作し、各ブロックについて次の具体的な手順を実行します。
- 状態をコピーして作業変数に代入します。a = A、b = B、c = C、d = D。
- 64回の操作を実行します。これは16回の操作からなる4ラウンドに編成されます。各操作は次の形式です。
a = b + ((a + f(b, c, d) + M[i] + K[i]) <<< s[i])- ここで
fはラウンド固有の非線形関数、M[i]は入力の32ビットワード、K[i]は事前定義された定数、s[i]は回転量です。
- 状態を更新します。A += a、B += b、C += c、D += d。
ラウンド関数は次のとおりです。
- 第1ラウンド(F):
(b & c) | (~b & d)— 選択関数 - 第2ラウンド(G):
(b & d) | (c & ~d)— 選択関数 - 第3ラウンド(H):
b ^ c ^ d— XOR関数 - 第4ラウンド(I):
c ^ (b | ~d)— AND/XOR関数
64個の定数K[i]は正弦関数から導出されます。具体的には、K[i] = floor(2^32 * |sin(i + 1)|) で、iは0から63の範囲です。これらの定数は多様な値の集合を提供し、雪崩効果(入力の1ビットを変えると出力ビットの約半分が変わる性質)を確実にするのに役立ちます。
ハッシュアルゴリズムの比較
MD5が現代の暗号技術の中でどの位置にあるかを理解するには、他のハッシュ関数と直接比較するとよいでしょう。
| アルゴリズム | 出力サイズ | 衝突耐性 | 速度 | 推奨 |
|---|---|---|---|---|
| MD5 | 128ビット(32文字) | なし(破綻) | 高速 | いいえ |
| SHA1 | 160ビット(40文字) | なし(破綻) | 高速 | いいえ |
| SHA256 | 256ビット(64文字) | あり | 中程度 | はい |
| SHA512 | 512ビット(128文字) | あり | 低速 | はい |
| SHA3 | 256〜512ビット | あり | 中程度 | はい |
MD5はこれらのアルゴリズムの中で最速です。ラウンド関数が最も単純で、内部状態のビット数が最も少ないためです。しかし、この速さは安全性と引き換えに得られています。出力が128ビットであるということは、誕生日のパラドックスにより、理論上は約2^64回の操作で衝突が見つかり得ることを意味します。現代の攻撃では、これが実用的なレベルまで引き下げられています。
SHA256はソフトウェア実装においてMD5より約3〜5倍遅いものの、256ビットの出力と128ビットの衝突耐性を提供します。ほとんどのアプリケーションでは、ハッシュ計算がボトルネックにならないため、この性能差は問題になりません。唯一の例外は、極端に大きなファイルをハッシュ化する場合や、毎秒数百万のハッシュを処理する場合ですが、そのような場合でもハッシュ関数の選択はセキュリティ要件によって決めるべきです。
一般的な使用例
既知の脆弱性にもかかわらず、MD5は衝突耐性を必要としないいくつかの用途で使われ続けています。
| 用途 | 適切か | 代替 |
|---|---|---|
| ファイルの完全性(セキュリティ目的でない) | はい | チェックサムならMD5で問題ない |
| パスワード保存 | いいえ | bcrypt、argon2を使用 |
| デジタル署名 | いいえ | SHA256を使用 |
| SSL証明書 | いいえ | SHA256を使用 |
| 重複ファイルの検出 | はい | MD5で十分機能する |
| ダウンロードのチェックサム | はい | 多くのサイトがいまもMD5を使用 |
ファイルの完全性(セキュリティ目的でない)
セキュリティ目的でない文脈でのファイル完全性検証では、MD5で十分な場合があります。ダウンロードしたファイルが転送中に破損していないかを確認する場合、MD5は他のどのハッシュ関数と同様に信頼性高く偶発的な破損を検出します。ランダムな転送エラーが衝突を引き起こす確率は、事実上ゼロです。
重複ファイルの検出
重複ファイルの検出も、もう1つの正当な用途です。ファイル同期ツール、バックアップソフトウェア、コンテンツアドレス指定ストレージシステムは、ハッシュを使って同一ファイルを素早く特定します。こうしたシナリオでは、MD5の衝突は実用上の問題になりません。攻撃者が意図的に衝突するファイルを作成する必要があり、衝突の結果はセキュリティ侵害ではなく誤一致に限られるからです。
ダウンロードのチェックサム
チェックサムによるダウンロード検証では、MD5はいまも多くのソフトウェアプロジェクトで使われています。ただし、これはレガシーな慣行です。現代のソフトウェア配布では、代わりにSHA256やSHA512のチェックサムを使う例が増えています。ソフトウェアを配布する場合は、MD5チェックサムの代わりに、あるいはそれに加えてSHA256チェックサムを提供すべきです。
MD5が適さない用途
MD5はセキュリティに関わるアプリケーションで決して使ってはいけません。以下の用途には衝突耐性のあるハッシュ関数が必要であり、これらのいずれかでMD5を使うとセキュリティ上の脆弱性を生み出します。
パスワード保存
レガシーシステムでは一般的な慣行ですが、MD5でパスワードハッシュを保存するのは危険なほど安全ではありません。MD5は十分に高速であるため、攻撃者はGPUハードウェア上で毎秒数十億のハッシュを計算でき、MD5パスワードハッシュに対するブルートフォース攻撃が非常に効果的になります。代わりにbcrypt、scrypt、argon2を使用してください。
デジタル署名
デジタル署名はその安全性を衝突耐性に依存しています。攻撃者が同じMD5ハッシュを持つ2つの文書を見つけられれば、署名者を騙して一方の文書に署名させ、その署名を両方の文書に適用させることができます。これは2008年のMD5に対する選択プレフィックス衝突攻撃で実際に実証されています。
SSL/TLS証明書
認証局はMD5を使って証明書に署名してはいけません。2008年、研究者はMD5の衝突を悪用して不正な認証局証明書を作成できることを実証し、これがCA/Browser ForumのガイドラインにおけるMD5の非推奨につながりました。主要な認証局はすべて、2009年までにMD5署名付き証明書の発行を停止しました。
暗号学的コミットメント
当事者が値のハッシュを公開してコミットし、後で値を明かすという形でハッシュ関数をコミットメントとして使うプロトコルには、衝突耐性が必要です。MD5によるコミットメントは、衝突を見つけることで破られます。
MD5衝突の年表
暗号解析によるMD5の段階的な弱体化は、暗号プリミティブが時間とともにどのように劣化するかを示す教科書的な例です。
| 年 | 出来事 |
|---|---|
| 1993 | Den BoerとBosselaersがMD5圧縮関数に擬似衝突を発見 |
| 1996 | 最初の衝突脆弱性を発見(Dobbertin) |
| 2004 | 最初の実用的な衝突を実証(Wangら) |
| 2005 | 標準的なPCで1時間以内に衝突を発見可能に |
| 2008 | 選択プレフィックス衝突攻撃(Stevensら) |
| 2012 | マルウェアFlameがMD5衝突を使いMicrosoftのコード署名を偽装 |
| 2017 | Googleが単一GPUで数時間で衝突を生成 |
2004年の中国人暗号解析者Xiaoyun Wangとそのチームによるブレークスルーは転換点でした。彼らは独自の差分暗号解析手法を用いてMD5の衝突を見つける方法を実証しました。この攻撃にはIBM P690スーパーコンピュータで約1時間かかりました。1年以内に、この攻撃は標準的なパーソナルコンピュータで実行できるよう最適化されました。
2008年のMarc Stevensらによる選択プレフィックス衝突攻撃はさらに影響が大きいものでした。この攻撃により、攻撃者は任意に選んだプレフィックスを持つ2つのメッセージで同じMD5値になるものを作成できます。両方の文書の内容を攻撃者が制御できるため、以前の衝突攻撃よりはるかに実用的です。チームは同じMD5署名を持つ2つの異なるSSL証明書を作成することでこれを実証しました。
2012年のマルウェアFlameの攻撃では、MD5衝突を使ってMicrosoft署名済みの正規ソフトウェアを装い、MD5に対する理論上の攻撃が国家安全保障に現実の影響をもたらすことを示しました。
セキュリティ上の懸念
MD5は暗号学的に破綻していると考えられています。核心的な問題は、MD5の128ビット出力が現代のセキュリティ要件には単純に小さすぎることです。MD5の誕生日限界による衝突耐性は2^64回の操作であり、現代の計算ハードウェアの到達範囲内に十分収まります。2009年には、標準的なデスクトップコンピュータでMD5衝突を見つけるのに約2^24秒(約2時間)かかりました。2017年には、同じ攻撃が単一のGPUで数分で済むようになりました。
衝突攻撃に加えて、MD5はブルートフォースより高速な原像攻撃にも脆弱です。MD5に対する原像攻撃の実用的影響は衝突攻撃ほど深刻ではありませんが、アルゴリズムへの信頼をさらに損ないます。
セキュリティに関わるアプリケーションでは、SHA-256またはSHA-3を使用してください。これらのアルゴリズムは128ビット以上の水準で衝突耐性を提供し、今後数十年にわたり安全であり続けると期待されています。パスワード保存には、ソルト生成と設定可能なワークファクターを備えた専用のパスワードハッシュ関数を使用してください。
無料ツール
セキュリティ上の弱点があるにもかかわらず、MD5はチェックサム、重複検出、重要でないデータの簡易フィンガープリントといったセキュリティ以外のタスクでは依然として有用です。こうしたセキュリティ目的でない用途向けに、MD5ジェネレーターツールを使ってオンラインで手軽にMD5ハッシュを生成できます。