MD5 vs SHA-256 vs SHA-512 — ハッシュ関数を解説
ハッシュ関数はソフトウェア開発のあらゆる場所にあります: ファイル整合性チェック、パスワード保存、デジタル署名、API 認証、キャッシュキー、重複排除。しかし、ほとんどの開発者はそれらをブラックボックスとして扱います — 文字列を入れて、固定長の 16 進ダイジェストを受け取ります。どのハッシュ関数を使い、どれを避けるべきかの詳細は、結局のところ非常に重要であることがわかります。
MD5 は破られています。SHA-1 は非推奨です。SHA-256 と SHA-512 は現在安全です。将来性が欲しい場合は SHA-3 が存在します。しかし「破られている」はすべての文脈で同じことを意味しません — MD5 は一部のユースケースでは問題ないが、他では破滅的に間違っています。このガイドでは、重要な特性、各関数がそれらにどう立ち向かうかを説明し、2026 年に正しいハッシュを選択するための明確な意思決定フレームワークを提供します。
ハッシュ関数が実際に行うこと
暗号ハッシュ関数は、任意の長さの入力を固定長の出力 (ダイジェストまたはハッシュ) にマッピングします。3 つの特性が暗号的に安全なハッシュ関数を定義します:
- 原像耐性 — ハッシュ
hが与えられたとき、hash(m) = hとなる任意の入力mを見つけることが計算的に不可能であるべきです。これは「一方向」の特性です。 - 第二原像耐性 — 入力
m1が与えられたとき、hash(m1) = hash(m2)となる異なる入力m2を見つけることが不可能であるべきです。 - 衝突耐性 —
hash(m1) = hash(m2)となる任意の 2 つの異なる入力m1とm2を見つけることが不可能であるべきです。
これらの特性のいずれかが失敗する関数は、暗号的使用には破られていると考えられます。「不可能」にはここで特定の意味があることに注意してください: 数学的に不可能を意味するのではなく、現在または予見可能なハードウェアで実用的なよりも多くの計算が必要であることを意味します。
さらに、暗号ハッシュ関数はアバランシェ効果を示します: 入力で 1 ビットを変更すると、ビットの約半分で異なる出力が生成されます。これにより、類似の入力が完全に異なるダイジェストを生成することが保証されます。
入力: "hello"
MD5: 5d41402abc4b2a76b9719d911017c592 (128 ビット / 32 16 進文字)
入力: "Hello"
MD5: 8b1a9953c4611296a827abf8c47804d7 (1 文字変更 = 完全に異なる出力) MD5 — 高速、普及、そして破られている
歴史と設計
MD5 (Message Digest 5) は 1991 年に Ron Rivest によって設計され、128 ビット (16 バイト) ダイジェストを生成します。1990 年代のほとんどの間、ファイル整合性検証、証明書署名、パスワードハッシュの標準的な選択肢でした。非常に高速です — 現代の CPU は毎秒数千万の MD5 ハッシュを計算でき、GPU は数十億計算できます。
なぜ MD5 は破られているのか
2004 年に、Xiaoyun Wang と同僚は MD5 に対する実用的な衝突攻撃を実証しました — 同じ MD5 ハッシュを生成する 2 つの異なるファイル。攻撃は消費者向けハードウェアで数分で実行されます。2008 年、研究者は MD5 衝突を使って不正な CA 証明書を作成し、実世界の PKI インフラストラクチャが脆弱であることを実証しました。2012 年までに、Flame マルウェアは MD5 衝突を使って Microsoft のコード署名証明書を偽造しました。
NIST は、ほとんどの暗号的使用に対して MD5 を公式に非推奨にしました。証明書当局は 2009 年までに MD5 で署名された証明書の発行を停止しました。ブラウザベンダーは 2011 年頃に MD5 証明書署名のサポートを削除しました。
MD5 がまだ許容される場合
MD5 は普遍的に役に立たないわけではありません。非セキュリティチェックサム — ファイル転送での偶発的なデータ破損の検出、攻撃者が入力に影響を与えることができないキャッシングシステムでのコンテンツベースのアドレッシング、または閉じた内部システムでの一意の識別子の生成 — には、MD5 は依然として十分です。重要なテスト: 攻撃者が衝突を作成することから利益を得ることができる場合、MD5 を使用しないでください。偶発的な破損のみが重要な場合、MD5 は問題ありません。
- 安全: 内部重複排除、キャッシュキー、非セキュリティファイル変更検出
- 安全でない: 証明書、デジタル署名、パスワードハッシュ、ファイル真正性検証、セキュリティトークン
SHA-1 — 非推奨、まだ死んでいない
SHA-1 は 160 ビットダイジェストを生成し、MD5 の後継でした。2000 年代のほとんどの間、証明書署名とコード署名の標準のままでした。2017 年に、SHAttered 攻撃は最初の実用的な SHA-1 衝突を実証し、約 110 GPU 年の計算を使って同じ SHA-1 ハッシュを持つ 2 つの異なる PDF ファイルを生成しました — 高価ですが、国家予算内に十分収まり、ますますアクセス可能になっています。
SHA-1 は NIST とすべての主要な証明書当局によって非推奨です。証明書、コード署名、または新しいセキュリティに敏感なアプリケーションには使用しないでください。一部のレガシーシステムは内部で SHA-1 を使用していますが、SHA-256 への移行が強く推奨されます。Git はまだオブジェクトアドレッシングに SHA-1 を使用していますが (SHA-256 への移行が進行中)、これは段階的に廃止されています。
SHA-256 — 現在の標準
SHA-256 は、NSA によって設計され、2001 年に FIPS 180-4 で NIST によって標準化された SHA-2 ファミリーの一部です。256 ビット (32 バイト) ダイジェストを生成します。SHA-256 は 2001 年の公開以来集中的に分析されており、実用的な攻撃は見つかっていません。次の事実上の標準です:
- TLS 証明書 (現在発行されているすべての証明書は基本的に SHA-256 を使用)
- コード署名 (Windows Authenticode、Apple 認証、JAR)
- API 認証用 HMAC-SHA256 (AWS Signature v4、GitHub Webhook 検証)
- JWT トークン署名 (HS256 と RS256 は両方とも内部で SHA-256 を使用)
- ブロックチェーンのトランザクション ID (Bitcoin はダブル SHA-256 を使用)
- パッケージマネージャーでのファイル整合性検証 (npm、pip、apt)
入力: "hello"
SHA-256: 2cf24dba5fb0a30e26e83b2ac5b9e29e1b161e5c1fa7425e73043362938b9824
(256 ビット / 64 16 進文字)
SHA-512: 9b71d224bd62f3785d96d46ad3ea3d73319bfbc2890caadae2dff72519673ca72323c3d
99ba5c11d7c7acc6e14b8c5da0c4663475c2e5c3adef46f73bcdec043
(512 ビット / 128 16 進文字) SHA-256 のパフォーマンス
SHA-256 は内部で 32 ビットワード演算を使用します。32 ビットハードウェアまたはハードウェアアクセラレーションのない古い CPU では、MD5 より明らかに遅いです。SHA 拡張を持つ現代の 64 ビット CPU (Intel Goldmont+、AMD Zen+、Apple Silicon、ARM Cortex-A57+) では、SHA-256 はハードウェアアクセラレーションされ非常に高速です — しばしば MD5 速度に近づきます。ほとんどのサーバー環境にはハードウェアアクセラレーションがあるため、実際には SHA-256 は事実上すべてのアプリケーションで十分に高速です。
SHA-512 — より広く、ときには高速
SHA-512 は内部で 64 ビットワード演算を使って 512 ビット (64 バイト) ダイジェストを生成します。SHA 拡張のない 64 ビットハードウェアでは、64 ビット演算が現代のレジスタ幅をよりよく活用するため、SHA-512 は実際に SHA-256 より速いことがあります。SHA 拡張を持つハードウェアでは、拡張が特に SHA-256 用に最適化されているため、SHA-256 が通常より速いです。
SHA-512 はより大きなセキュリティマージン — SHA-256 の 128 ビットに対して 256 ビットの衝突耐性 — を提供します。ほとんどの現在の脅威モデルでは、SHA-256 の 128 ビット衝突耐性で十分以上です (それを破るには約 2^128 回の演算が必要です)。SHA-512 は次の場合に適切です:
- 64 ビットサーバーをターゲットにしており、ハードウェア拡張なしで最大スループットが欲しい場合
- 他の暗号操作のための鍵材料としてより長いダイジェストが必要な場合
- 数十年にわたって保護されたままでなければならないデータに追加のセキュリティマージンが欲しい場合
- 特に SHA-512 を求めるプロトコル (たとえば、一部の TLS 暗号スイート) を実装している場合
SHA-384 と SHA-512/256
SHA-384 は SHA-512 の切り捨てバージョンで、384 ビットを生成します — SHA-512 の 64 ビット内部演算が欲しいがより短い出力が必要な場合に有用です。SHA-512/256 は、SHA-512 の内部計算を使って 256 ビット出力を生成する別の切り捨てバリアントです。SHA-512/256 は、SHA-256 に影響を与える長さ拡張攻撃に耐性があり、長さ拡張が懸念事項である文脈で有用です (ただし、HMAC はほとんどの実用的なシナリオですでにこれを軽減します)。
SHA-3 — 異なるアーキテクチャ、将来性
SHA-3 (2015 年 NIST FIPS 202 で標準化) は Keccak スポンジ構造を使用します — SHA-2 の Merkle-Damgard 構造とは根本的に異なる設計です。これは重要です。Merkle-Damgard 設計で将来発見される弱点は、MD5、SHA-1、SHA-2 を同時に影響しますが、SHA-3 は影響を受けません。
SHA-3 は現在安全であり、長期的な保証が必要な、または将来の SHA-2 の弱点に対するヘッジが欲しい新しいシステムにとって正しい選択肢です。純粋なソフトウェア実装では SHA-256 より遅いです。SHA-3 が優れているのは、ハードウェア実装です — その設計はシリコンで非常に効率的です。SHA-3-256 と SHA-3-512 は、SHA-2 のカウンターパートと同じダイジェストサイズを生成します。
比較表
| アルゴリズム | 出力 | 衝突耐性 | ステータス | 速度 (SW) | パスワードに使う? |
|---|---|---|---|---|---|
| MD5 | 128 ビット | 破られている | 非推奨 | 非常に高速 | 絶対に使わない |
| SHA-1 | 160 ビット | 破られている | 非推奨 | 高速 | 絶対に使わない |
| SHA-256 | 256 ビット | 128 ビット | 現在の標準 | 高速 (HW アクセル) | 絶対に使わない (速すぎる) |
| SHA-512 | 512 ビット | 256 ビット | 安全 | 64 ビットで高速 | 絶対に使わない (速すぎる) |
| SHA-3-256 | 256 ビット | 128 ビット | 将来性 | 中程度 (SW) | 絶対に使わない (速すぎる) |
| bcrypt | 60 文字の文字列 | 該当なし | パスワード専用 | 意図的に遅い | はい |
パスワードハッシュ: まったく異なる問題
これは独自のセクションに値します。開発者が犯す最も一般的な間違いの 1 つだからです。SHA-256 はファイル整合性チェック、API 署名、証明書検証に適したツールです。パスワードのハッシュ化には適切でないツールであり、その目的に使用すると実際のセキュリティインシデントを引き起こします。
問題は速度です。SHA-256 は高速に設計されています — 現代の GPU は毎秒数十億の SHA-256 ハッシュを計算できます。ハッシュ化されたパスワードデータベースを取得した攻撃者は、毎秒数十億のパスワード推測を試みることができます。ハッシュが高速であれば、長くてランダムなパスワードでも素早くクラックできます。
// パスワードにはこれを決してしてはいけない
const hash = crypto.createHash('sha256').update(password).digest('hex'); // パスワードには bcrypt、scrypt、または Argon2 を使用
const bcrypt = require('bcrypt');
const hash = await bcrypt.hash(password, 12); // コスト係数 12 Bcrypt Test ツールを使うと、ブラウザで bcrypt パスワードをハッシュおよび検証できます。bcrypt のコスト係数とその計算時間を理解するには、アプリケーションの作業係数を設定するときの有用なリファレンスです。
HMAC: ハッシュに認証を追加
通常のハッシュは、誰が計算したかについて何も証明しません — データを持つ人は誰でも同じ SHA-256 ハッシュを計算できます。HMAC (Hash-based Message Authentication Code) は、計算に秘密鍵を追加し、その鍵を知っている人のみが再現できるタグを生成します。HMAC-SHA256 は次の標準です:
- Webhook 署名検証 (GitHub、Stripe、Shopify はすべて HMAC-SHA256 を使用)
- AWS Signature Version 4 (リクエスト署名)
- JWT HS256 トークン (ヘッダー + ペイロードの HMAC-SHA256)
- Cookie 整合性 (改ざんを防ぐためにセッション Cookie に署名)
const crypto = require('crypto');
// HMAC-SHA256 でメッセージに署名
const mac = crypto
.createHmac('sha256', secretKey)
.update(message)
.digest('hex');
// 検証: 定数時間で比較 (タイミング攻撃を防止)
const isValid = crypto.timingSafeEqual(
Buffer.from(mac, 'hex'),
Buffer.from(received, 'hex')
);
比較に timingSafeEqual を使用していることに注意してください。通常の文字列等価チェックで MAC 値を比較すると、タイミング攻撃で悪用できるタイミング情報が漏洩します。MAC を検証するときは常に定数時間比較関数を使用してください。コードを書かずにテストとデバッグのために HMAC-SHA256 値を計算するには、HMAC Generator を使用してください。
実世界の推奨事項
一般的なファイル整合性 (チェックサム)
SHA-256 を使用してください。パッケージ検証 (npm ロックファイル、pip 要件ハッシュ、Docker イメージレイヤー) の標準です。SHA-256 Hash ツールは、テキスト入力または文字列値のために SHA-256 ダイジェストをブラウザで計算します。速度が重要で送信元を信頼する素早い非セキュリティチェックサムには、MD5 が依然として許容されますが、共有または自動化されたコンテキストでは SHA-256 が好ましいです。
TLS 証明書とコード署名
SHA-256 が必須の標準です。すべての証明書当局が SHA-256 証明書を発行します。新しい証明書には MD5 や SHA-1 を使用しないでください — 現代のブラウザとオペレーティングシステムによって拒否されます。
API 認証
HMAC-SHA256 を使用してください。確立された標準で、すべての言語でよくサポートされており、ほとんどの API セキュリティドキュメントが期待するアルゴリズムです。素早い比較のために MD5 Hash ツールや SHA-256 Hash ツールでダイジェストを計算し、HMAC Generator で HMAC 署名を生成します。
パスワードハッシュ
bcrypt (コスト係数 12+)、scrypt、または Argon2id を使用してください。ソルティングを使用しても、パスワードに直接 MD5、SHA-1、SHA-256、または SHA-512 を使用しないでください。Bcrypt Test ツールは、開発中に bcrypt ハッシュを検証するのに役立ちます。
数十年のセキュリティが必要な長寿命データ
SHA-512 または SHA-3-256 を優先してください。より大きなダイジェストサイズが、暗号解析の進歩に対する追加のマージンを提供します。NIST は、長期的なセキュリティを必要とするアプリケーションに対して SHA-512 と SHA-3 を推奨します。SHA-2 アルゴリズムの権威ある仕様については、NIST FIPS 180-4 の公式ガイダンスを参照してください。
レガシー制約のない新しいシステム
一般的な使用には SHA-256。パスワードには Argon2id。認証コードには HMAC-SHA256。将来性が欲しく、わずかに低いパフォーマンスを受け入れられる場合、SHA-3-256 は一般的な目的のハッシュに SHA-256 の堅実な代替手段です。