大きなファイルをダウンロードすると、ダウンロードページに d41d8cd98f00b204e9800998ecf8427e のような謎の文字列と「MD5」という表記を見かけることがあります。これは何を意味するのでしょうか?本記事ではハッシュ関数の基本概念から始め、MD5の動作原理・セキュリティの現状、そして各シーンに適したハッシュアルゴリズムの選び方を詳しく解説します。
1. ハッシュ関数とは?
ハッシュ関数(Hash Function)とは、任意長の入力データを固定長の出力値(「ハッシュ値」「ダイジェスト」とも呼ぶ)に変換する数学的な関数です。優れたハッシュ関数は以下の性質を持ちます:
- 決定論的:同じ入力からは常に同じ出力が得られる
- 固定長出力:入力の長さに関係なく出力長は固定(MD5は128ビット=32桁の16進数)
- 雪崩効果:入力の1ビットが変わると、出力の約50%のビットが変化する
- 一方向性(原像困難性):ハッシュ値から元の入力を逆算することは計算上ほぼ不可能
- 衝突耐性:同じ出力を生む2つの異なる入力を見つけることが困難
暗号化は可逆(正しい鍵があれば復号できる)、ハッシュは一方向(復元不可能)です。用途が根本的に異なり、混同するとセキュリティ上の重大なミスにつながります。
2. MD5の動作原理
MD5(Message Digest Algorithm 5)はRon Rivestが1991年に設計したMD4の改良版です。128ビット(16バイト)の出力を生成し、通常32桁の小文字16進数で表記されます。
2.1 処理フローの概要
- パディング:入力データの長さが512で割って448ビット余るよう調整し、末尾に元の長さを64ビットで付加
- 初期化:4つの32ビット状態値(A、B、C、D)を固定定数で初期化
- ブロック処理:パディング済みデータを512ビットのブロックに分割し、各ブロックに4ラウンド・計64回の非線形演算を適用
- 出力:最終的な4つの32ビット値を連結して128ビットのダイジェストを生成
2.2 例
同じ入力からは常に同じMD5が得られます:
MD5("") = d41d8cd98f00b204e9800998ecf8427e
MD5("hello") = 5d41402abc4b2a76b9719d911017c592
MD5("Hello") = 8b1a9953c4611296a827abf8c47804d7
「hello」と「Hello」は大文字・小文字が1文字違うだけですが、MD5値は全く異なります——これが「雪崩効果」の現れです。
3. MD5のセキュリティ上の問題
3.1 衝突攻撃(Collision Attack)
2004年、王小雲教授のチームがMD5の衝突——つまり異なる2つの入力から全く同じMD5値を生成すること——に成功しました。これは攻撃者が正規のファイルと同じMD5を持つ悪意あるファイルを作成し、整合性検証を突破できることを意味します。
2008年には研究者がMD5衝突を利用して偽のSSL証明書を作成し、現実世界での攻撃の可能性を実証しました。
3.2 レインボーテーブル攻撃
MD5の計算は非常に高速で、現代のGPUは1秒あたり数十億のMD5を計算できます。攻撃者は「平文→MD5値」の大規模な対照表(レインボーテーブル)を事前に構築し、容量と引き換えに高速でパスワードの平文を逆引きできます。
これが、現代のパスワード保存にMD5(またはSHA-1・SHA-256)を直接使ってはいけない理由です——ソルトを加えても、パスワード専用設計の関数ほど安全ではありません。
3.3 長さ拡張攻撃(Length Extension Attack)
MD5(SHA-1・SHA-256も同様)は長さ拡張攻撃に脆弱です。攻撃者は元のデータを知らなくても有効なMAC(メッセージ認証コード)を偽造できる可能性があります。SHA-3とHMAC構造はこの攻撃の影響を受けません。
4. MD5 vs 他のハッシュアルゴリズム
| アルゴリズム | 出力長 | 安全性 | 速度 | 適用場面 |
|---|---|---|---|---|
| MD5 | 128 bit | 破られている(衝突既知) | 非常に速い | 非セキュリティ用途のチェックサムのみ |
| SHA-1 | 160 bit | 破られている(2017年に実際の衝突) | 速い | 新システムへの使用は非推奨 |
| SHA-256 | 256 bit | 安全(既知の衝突なし) | 中程度 | デジタル署名・証明書・一般的なセキュリティ用途 |
| SHA-3 | 可変 | 安全(異なる設計原理) | やや遅い | 高セキュリティ要件 |
| bcrypt | 固定 | パスワード専用設計・ブルートフォース耐性 | 遅い(意図的設計) | パスワード保存 |
| Argon2 | 可変 | PHC 2015優勝 | 遅い(意図的設計) | パスワード保存(推奨) |
5. MD5の正しい使いどころ
5.1 ✅ セキュリティ目的ではないファイル整合性の確認
ダウンロードや転送中にファイルが破損していないか確認するため(注意:悪意ある改ざんは防げません)。悪意ある改ざんが心配な場合はSHA-256を使ってください。
5.2 ✅ 重複排除とキャッシュキー
コンテンツの一意な識別子としてMD5を使い、2つのデータが同一かどうかを判定したり、キャッシュシステムのキーとして使います。セキュリティとは無関係で、MD5の決定論的な性質と速度を活用するだけです。
5.3 ✅ 非パスワード目的のデータインデックス
大量のテキストのMD5をデータベースのインデックスキーとして計算し、固定長・均等分布の特性を活かして検索効率を上げます。
5.4 ❌ パスワード保存
MD5(または任意の汎用ハッシュ関数)でパスワードを保存することは絶対に避けてください。bcrypt・Argon2・scryptなどパスワード専用設計の関数を使いましょう。
5.5 ❌ デジタル署名と証明書
MD5の衝突脆弱性により、X.509証明書署名・コード署名・偽造防止が必要なあらゆる場面での使用は不適切です。SHA-256以上を使ってください。
5.6 ❌ HMACの基礎ハッシュ
HMAC-MD5は理論上は素のMD5より安全ですが、現代システムではHMAC-SHA256への移行を推奨します。
6. MD5の計算方法
# コマンドライン(Linux/macOS)
md5sum file.txt # Linux
md5 file.txt # macOS
# PHP
md5('hello') // 5d41402abc4b2a76b9719d911017c592
md5_file('file.txt') // ファイルのMD5を計算
# Python
import hashlib
hashlib.md5(b'hello').hexdigest()
# JavaScript(crypto-jsライブラリを使用)
CryptoJS.MD5('hello').toString()
または本サイトのMD5ツールを使えば、ブラウザ上でインストール不要でテキストのMD5値を計算できます。
7. よくある質問
7.1 MD5とBase64は何が違うのですか?
MD5はハッシュ(一方向・不可逆)、Base64はエンコーディング(双方向・可逆)です。性質が根本的に異なり、混同するとセキュリティ上の問題が生じます。
7.2 ソルトを加えればMD5をパスワード保存に使えますか?
ソルトはレインボーテーブル攻撃を防げますが、MD5が速すぎるという根本的な問題は解決しません。ソルトを加えても、現代のGPUは1秒あたり数十億回の試行が可能です。bcryptかArgon2を使ってください。
7.3 「MD5衝突」とは何ですか?なぜ重要なのですか?
衝突とは、異なる2つの入力が同じMD5値を生成することです。現在では数秒でMD5衝突を生成するツールが存在し、攻撃者は正規ファイルと同じMD5を持つ悪意あるファイルを作成し、MD5検証に依存するシステムを欺ける可能性があります。
8. まとめ
MD5は優れた設計を持ち広く普及したハッシュアルゴリズムですが、暗号学的なセキュリティはすでに破られています。その限界を理解することはすべての開発者の基本知識です:非セキュリティ目的の整合性確認やデータ識別には今も有用ですが、パスワード保存・デジタル署名・悪意ある攻撃への耐性が必要な場面では使うべきではありません。そのような場面では、SHA-256(汎用)またはArgon2(パスワード)が適切な選択肢です。