記事一覧へ戻る
フォーマット比較

SHA-256 vs MD5 vs SHA-1 — どのハッシュアルゴリズムを選ぶべきか

ファイル整合性チェック・パスワード保存・電子署名で使う 3 種類のハッシュを、衝突耐性・速度・実用上の安全性で比較。MD5 / SHA-1 が「壊れている」とされる理由も整理します。

何で選ぶか — 4 つの判断軸

ハッシュアルゴリズム選びは「強い順に並べて一番上を採用」ではありません。衝突耐性 (異なる入力が同じハッシュになる攻撃に耐えられるか) は改ざん検知や署名で必須ですが、用途によっては不要なこともあります。出力サイズ (128 / 160 / 256 / 512 bit) はストレージ・URL 長・キー設計に効きます。計算速度 は大量のファイルをハッシュ化するパイプライン (バックアップ整合性チェック、CDN の ETag) で無視できない差になります。標準と互換性 は、TLS 証明書・Git の object ID・既存のチェックサム配布形式といった「相手側が何を期待しているか」を決めます。

「新しいものほど良い」は正しい方向ではあっても、「MD5 を使ったから即危険」「SHA-256 にしたから安心」というような単純な置き換えにはなりません。攻撃モデル (誰が、何を、どう改ざんしようとするか) を意識せずに選ぶと、Argon2 を使うべき場面で SHA-256 を使ってパスワードを保存してしまう、といった事故になります。

3 つのハッシュを並べて見る

項目MD5SHA-1SHA-256
出力長128 bit (16 byte)160 bit (20 byte)256 bit (32 byte)
16 進表記の長さ32 文字40 文字64 文字
設計Merkle-Damgård (Rivest, 1991)Merkle-Damgård (NIST, 1995)SHA-2 ファミリ (NIST, 2001)
衝突発見2004 (Wang)、現実的攻撃可2017 (Google SHAttered, 約 110 GPU 年)未発見
推奨用途整合性チェックの簡易確認のみ既存システムとの互換用途のみ改ざん検知・署名・TLS・ブロックチェーン
速度 (相対)1.0 (基準・最速)約 1.2 倍遅い約 1.5-2 倍遅い
標準対応RFC 1321 (廃止勧告)NIST SP 800-131A で 2030 廃止NIST FIPS 180-4 現役

MD5 は 2004 年に Wang らが衝突生成に成功して以降、2008 年には実在の証明書を偽造する攻撃 (Sotirov ら) まで実証され、改ざん検知の用途では完全に終わっています。SHA-1 は 2017 年に Google と CWI が「SHAttered」で 2 つの異なる PDF が同じ SHA-1 を持つ衝突を公開し、ブラウザ各社が TLS 証明書で SHA-1 を拒否済み。SHA-256 は SHA-2 ファミリの一員で、2026 年時点で実用的な衝突は発見されていません。補足として BLAKE2 / BLAKE3 は SHA-256 より速く同等以上のセキュリティ、SHA-3 (Keccak) は構造が異なる予備系として標準化されています。

場面別の使い分け

ファイルの改ざん検知 / リリース配布物の整合性: SHA-256。配布元の Web サイトに *.sha256 を併記し、ダウンロード後に再計算して一致を確認する運用が一般的です。MD5 や SHA-1 は「ダウンロード中のビット化けを検出」程度の用途に絞り、悪意ある第三者が中間で差し替えるシナリオでは使わない。

パスワード保存: ハッシュ単体は不可。SHA-256 を生で使うのは MD5 を生で使うのと同じレベルで危険です。レインボーテーブル攻撃と GPU/ASIC による総当たりが現実的なので、Argon2id (現代の推奨)、bcryptscrypt のような KDF (Key Derivation Function) にソルトを組み合わせて使う。SHA-256 はその内部で使われていることはあっても、アプリ側から直接呼ぶ場面ではない。

Git の object ID / 既存システムとの互換: SHA-1 が現役 (Git は将来 SHA-256 に移行予定)。既存 API が MD5 や SHA-1 を返すなら、それに合わせる以外の選択肢はないですが、新規設計で MD5/SHA-1 を選ぶ理由は基本ありません。

TLS 証明書 / コード署名 / JWT 署名: SHA-256 以上。SHA-1 証明書はモダンブラウザで弾かれます。JWT も HS256 / RS256 / ES256 のように SHA-256 ベースが標準です。

短い識別子 (キャッシュキー / ETag): 衝突耐性が要らないなら速度優先で MD5 でも構いません。ただし「将来この識別子が改ざん検知に流用される」リスクがあるなら最初から SHA-256 にしておく方が無難。

ブラウザ内でハッシュを計算する

ファイルや文字列のハッシュを取りたいときは hash-generate で MD5 / SHA-1 / SHA-256 / SHA-512 などを一度に計算できます。リリース ZIP の整合性確認、ダウンロード後の改ざんチェック、ログ行の同一性判定など、サーバーに送らずに済ませたい用途で便利です。

注意点は 3 つ。(1) 同じ入力なら同じ出力: ハッシュ検証は「元の値と計算結果が一致するか」を見るだけ。配布元が abc123... と公開している値と、ダウンロードしたファイルから計算した値を文字単位で比較するのが基本。(2) 改行コードに敏感: テキストファイルを CRLF と LF で読み込むと当然違うハッシュになります。Git on Windows の core.autocrlf 設定や、エディタの保存時 BOM 付与で値が変わるケースを忘れない。(3) パスワード比較は定数時間で: アプリ側で実装する場合、文字列の === は早期 return でタイミング攻撃の余地が残るので crypto.timingSafeEqual 相当を使う。ブラウザ計算実装は GitHub で公開しており、DevTools の Network タブで「ファイル本体がどこにも送信されていない」ことを目視確認できます。