TegaruTools
開発者ガイド

ハッシュ関数入門|MD5・SHA-1・SHA-256 の違いと安全な選び方

ファイルの整合性確認・パスワード保存・電子署名で使われるハッシュ関数。それぞれのアルゴリズムの違い・なぜMD5/SHA-1が非推奨か・パスワード保存にハッシュだけでは足りない理由まで解説します。

公開: 2026年6月17日読了 約10TegaruTools

ファイルのダウンロードページに書かれた「SHA-256: a3f8b9...」、Git のコミットID、パスワードリセットメールのトークン、ブロックチェーン——どれもハッシュ関数の出力です。

ハッシュは「データの指紋」をつくる仕組みで、現代のソフトウェアセキュリティと整合性検証の根底にあります。一方で「ハッシュをかければ安全」「MD5でもパスワード保存ならOK」など、誤解も多い分野です。この記事では、ハッシュの基本性質から、なぜ MD5/SHA-1 が非推奨になったのか、SHA-256 を選べばよい場面とそれだけでは不十分な場面まで、実用目線でまとめます。

ハッシュ関数とは — 任意長データから固定長の「指紋」を作る

ハッシュ関数は、どんな長さのデータ(1バイトでも1GBでも)からも、決まった長さの数値(ハッシュ値・ダイジェスト)を生成する関数です。同じ入力からは同じ出力が、わずかでも違う入力からはまったく違う出力が出ます。

例えば SHA-256 を使うと、入力サイズに関係なく出力は常に 32バイト(256ビット) です。16進数で書けば 64文字。

  • 「hello」→ 2cf24dba5fb0a30e26e83b2ac5b9e29e1b161e5c1fa7425e73043362938b9824
  • 「hellp」(最後を p に変えただけ)→ 7e5a... まったく違う値

この「データの指紋」のような性質が、整合性検証・パスワード保存・電子署名・コミット識別など、あらゆる場面で役立ちます。

暗号学的ハッシュに求められる3つの性質

実用的なハッシュ関数(暗号学的ハッシュ)には、次の3つの性質が要求されます。

  1. 原像計算困難性(preimage resistance):ハッシュ値から元のデータを逆算できない。一方向関数とも呼ばれる。
  2. 第二原像計算困難性(second preimage resistance):特定の入力 X が与えられたとき、X とは異なるが同じハッシュになる Y を見つけられない。
  3. 衝突困難性(collision resistance):「同じハッシュになる異なる2つの入力 X, Y」のペア自体を見つけられない。

この3つすべてが「現実的な計算量では破れない」ことが、安全な暗号学的ハッシュの条件です。技術が進むと、過去には安全だったアルゴリズムがこの性質を満たさなくなり、非推奨化されます。それが MD5 と SHA-1 の運命でした。

各アルゴリズムの位置づけ

MD5(Message Digest 5)

1991年に発表された、128ビット(16バイト)のダイジェストを生成するアルゴリズム。1990年代〜2000年代前半まで、整合性検証やパスワード保存にも使われていました。

しかし2004年に「衝突を実際に作れる」攻撃が発表され、さらに2008年には同じMD5を持つまったく異なる2つの CA証明書を作るというデモが実演されました。これにより MD5 は暗号学的な用途ではすべて非推奨になりました。

いまMD5を使ってよいのは「悪意のない偶発的な破損を検出する」用途、つまりファイル転送のチェックサム程度です。例えばダウンロードしたISOファイルが破損していないかの簡易チェック。それ以上の意図的な改ざんを想定するなら、MD5 では不十分です。

SHA-1(Secure Hash Algorithm 1)

1995年に NIST が標準化した、160ビット(20バイト)のアルゴリズム。MD5 と同様、長年に渡り標準として使われ、Gitのコミットハッシュやかつての SSL/TLS 証明書にも採用されていました。

2017年、Googleと CWI Amsterdam が「同じSHA-1を持つ異なる2つのPDFファイル」を実演(SHAttered攻撃)。SHA-1 の衝突は現実に作れることが証明され、暗号用途では完全に非推奨になりました。

現在も Git は SHA-1 を使っていますが、これは「悪意のある衝突を考慮しないコミット識別」用途であり、セキュリティ目的ではありません。Git も将来的にはSHA-256 への移行が進む見込みです。

SHA-256 / SHA-512(SHA-2ファミリー)

2001年に NIST が標準化した、SHA-1 の後継となるアルゴリズム群。SHA-256(32バイト)と SHA-512(64バイト)がよく使われます。

2026年現在、暗号学的ハッシュとして最も広く推奨されているのが SHA-256です。TLS証明書、デジタル署名、ブロックチェーン、ソフトウェアの完全性検証——あらゆる場面の標準。理論的な弱点も知られていません。

SHA-512 は出力が長い分、64bit CPU で高速に動き、結果として SHA-256 より速いこともあります。とくに大きなファイルのチェックサム用途では選ばれることがあります。

SHA-3(Keccak)

2015年に NIST が標準化した、SHA-2 とは内部構造がまったく異なるアルゴリズム。「SHA-2 が破られたときの保険」として用意されています。現状 SHA-2 が破られる兆候はなく、実用ではまだ SHA-256 が主流ですが、長期保管が必要なデータには SHA-3 を併用するケースも増えてきました。

用途別の選び方

ファイル整合性チェック(ダウンロード破損確認)

悪意のない単純な破損検出なら MD5 でも十分高速で実用的です。ただし配布元が改ざんされるリスクも考えると、現在は SHA-256 が業界標準。Linux ディストロ、Docker イメージ、Node.js のリリースなど、どれもSHA-256で公開されています。

電子署名・証明書

SHA-256(または SHA-384)一択。SHA-1 は2017年以降ブラウザにも信用されません。

パスワード保存

ここが最大の落とし穴です。パスワード保存に SHA-256 を「そのまま」使ってはいけません。後述する別の方式を使う必要があります。

識別子・キャッシュキー

「文字列を短い識別子に変換したい」だけなら、暗号学的安全性は不要なので、SHA-256 の一部を使う・MD5 を使う・あるいは非暗号のハッシュ(xxHash, FNV など)を使うのもあり。速度を優先したい用途では非暗号ハッシュが有利です。

パスワード保存にハッシュだけでは足りない理由

「パスワードを SHA-256 にしてDBに保存していれば安全」——これは大きな誤解です。理由は3つあります。

1. ハッシュ単体は同じ入力から同じ出力が出る

「password123」のSHA-256は常に同じ値です。事前に「よく使われるパスワード上位100万件」のSHA-256表(レインボーテーブル)を持っておけば、漏洩DBと照合するだけで多くのアカウントを破れます。

2. SHA-256は高速すぎる

SHA-256 は1秒間に数十億回計算できます。攻撃者が GPU を使えば、8桁程度のパスワードは総当たり計算で数時間以内に破れてしまいます。パスワード保存にはむしろ「遅いハッシュ」が必要です。

3. レインボーテーブル対策が必要

ユーザー固有のランダム値(ソルト)をパスワードに混ぜてからハッシュ化する必要があります。これにより、同じパスワードでもユーザーごとに異なるハッシュになり、事前計算表が使えなくなります。

解決策:パスワード専用ハッシュアルゴリズム

2026年現在、パスワード保存には次のいずれかを使うべきです。すべて「ソルト自動・ストレッチング(数千〜数十万回のハッシュ繰り返し)」が組み込まれています。

  • Argon2id:Password Hashing Competition の優勝アルゴリズム。新規プロジェクトの第一推奨。
  • bcrypt:1999年から使われ続けている定番。多くのフレームワーク(Rails / Django / Laravel)の標準。
  • scrypt:メモリ消費型。GPU/ASIC攻撃に強い。
  • PBKDF2:標準化されてはいるが、現代的にはbcrypt以上を推奨。

SHA-256 を直接呼び出さず、これらの「パスワード用ハッシュ」ライブラリを使うのが鉄則です。

HMAC — ハッシュとMACの違い

「メッセージが改ざんされていないか」を、共有秘密鍵を使って検証する仕組みが MAC(Message Authentication Code)です。代表が HMAC-SHA256

単なるハッシュとの違いは、秘密鍵を知っている人だけがその MAC を作れること。これにより「データの正当性」だけでなく「データを作った人の正当性」も検証できます。Webhookの真正性検証、API のリクエスト署名(AWS S3 など)でよく使われます。

各言語での扱い方

  • JavaScript(ブラウザ):標準の crypto.subtle.digest('SHA-256', data) が使える。Uint8Arrayを入出力するため変換コードがやや煩雑。
  • Node.jscrypto.createHash('sha256').update(text).digest('hex')
  • Pythonhashlib.sha256(b'hello').hexdigest()
  • PHPhash('sha256', 'hello')。パスワードは password_hash() を使う。
  • シェルsha256sum file.iso(Linux)、shasum -a 256 file.iso(macOS)。

本サイトの ハッシュ生成ツール なら、コーディング不要で MD5・SHA-1・SHA-256 をブラウザ上で計算できます。WebCrypto API を使っているので、入力データはサーバーに送信されません。

ハッシュにまつわるよくある誤解

  • 「ハッシュ=暗号化」ではない:暗号化は鍵で元に戻せるが、ハッシュは原則として元に戻せない(一方向)。
  • 「短いハッシュは速い」必ずしも:MD5(128bit)と SHA-256(256bit)の計算コストは出力サイズだけでは決まらない。むしろ最近のCPUは SHA-256 を命令単位で高速化している。
  • 「衝突が見つかった=全部破れる」ではない:MD5 が破れたといっても、特定のハッシュ値から元データを逆算できるわけではない(衝突困難性は破れたが、原像計算困難性はまだ生きている)。それでも署名等には使えないのでアウト。
  • 「SHA-256 の方が SHA-512 より安全」ではない:両方とも現状安全。SHA-512 は出力が長い分、衝突困難性のマージンが大きい。

まとめ — 用途別の早見表

  • ファイル破損検出(悪意なし):MD5 でもOK(速度優先)。ただ業界標準は SHA-256。
  • ファイル改ざん検出(悪意あり):SHA-256 必須。
  • 電子署名・TLS証明書:SHA-256 必須。MD5/SHA-1 は完全に非推奨。
  • パスワード保存:Argon2id・bcrypt・scrypt のいずれか。SHA-256単体はNG。
  • WebhookのHMAC検証:HMAC-SHA256。
  • 短い識別子・キャッシュキー:SHA-256 の先頭8〜16文字、もしくは非暗号ハッシュ。

実務でハッシュ値を試したいときは、本サイトの ハッシュ生成ツール でMD5・SHA-1・SHA-256をワンクリック計算できます。データはサーバーに送信されないので、機密文字列のハッシュ確認にも安心です。

この記事で紹介したツール

関連するガイド記事