Toolypet
ブログに戻る
Security

SHA-256 vs bcrypt vs Argon2 - 開発者のためのハッシュアルゴリズム完全比較

パスワード保存にSHA-256を使ってはいけない理由、bcryptとArgon2の違い、2026年推奨ハッシュ戦略を詳しく解説します。

Toolypet Team

Toolypet Team

Development Team

4 分で読めます

SHA-256 vs bcrypt vs Argon2:いつ何を使うべきか?

「パスワードをSHA-256でハッシュして保存すれば安全でしょ?」

この質問をする開発者は多いです。結論から言えば、パスワードにSHA-256を使用してはいけません

このガイドでは、ハッシュアルゴリズムの違いと各状況に適した正しい選択を解説します。


ハッシュ vs 暗号化:基本概念

ハッシュ(Hashing)

入力 → ハッシュ関数 → 固定長出力(復元不可)

"password" → SHA-256 → "5e884898da28047d..."
  • 一方向:元のデータを復元できない
  • 決定的:同じ入力 = 同じ出力
  • 固定長:入力サイズに関係なく一定の出力

暗号化(Encryption)

入力 + 鍵 → 暗号化 → 暗号文 → 復号化 + 鍵 → 元データ

"password" + key → AES → "Xyz..." → AES + key → "password"
  • 双方向:鍵で元データを復元可能
  • 鍵依存:鍵がないと復号化不可

パスワード保存にはハッシュを使用します。 元データを知る必要はなく、入力値とハッシュを比較するだけです。


ハッシュアルゴリズムの分類

高速ハッシュ(Fast Hash)

アルゴリズム出力長速度用途
MD5128ビット非常に高速❌ セキュリティ用途禁止
SHA-1160ビット高速❌ セキュリティ用途禁止
SHA-256256ビット高速ファイル整合性、デジタル署名
SHA-512512ビット高速ファイル整合性、ブロックチェーン

低速ハッシュ(Slow Hash / Password Hash)

アルゴリズム特徴2026年推奨
bcrypt時間調整可能(cost)
scryptメモリ集約型
Argon2最新、OWASP第1位✅✅
PBKDF2互換性が高い⚠️ レガシー

なぜSHA-256でパスワードを保存してはいけないのか?

理由1:速すぎる

SHA-256は速度のために設計されています。これはファイル整合性チェックには利点ですが、パスワード保存には致命的な欠点です。

現代GPUの性能:
- MD5:毎秒1,800億ハッシュ
- SHA-256:毎秒100億ハッシュ
- bcrypt(cost 12):毎秒1,000ハッシュ

8文字の複雑なパスワードでもSHA-256で保存すると数分でクラッキングされます。

理由2:Saltを手動で管理する必要がある

# ❌ 間違った方法
hash = sha256(password)

# 問題:レインボーテーブル攻撃に脆弱

# ⚠️ 改善したが依然として不十分
salt = generate_random_salt()
hash = sha256(salt + password)

# 問題:依然として速すぎる

理由3:GPUアクセラレーションに脆弱

SHA-256はGPUでの並列処理が容易です。攻撃者はゲーミングGPU数枚で膨大な速度でハッシュを計算できます。


bcrypt:27年間検証された標準

動作原理

bcrypt(cost, salt, password) → hash

cost:計算の反復回数(2^cost)
salt:22文字のランダム文字列(自動生成)

なぜbcryptが安全なのか?

  1. 意図的に遅い:cost factorで速度を調整
  2. 自動Salt:毎回異なるハッシュを生成
  3. メモリ集約型:GPUアクセラレーションが困難

Cost Factorガイド(2026年)

Costハッシュ時間推奨用途
10約100ms開発/テスト
12約250ms一般的なWebアプリ(推奨)
13-14約500ms高セキュリティ要件
15+1秒以上特殊目的

コード例

// Node.js with bcrypt
const bcrypt = require('bcrypt');

// ハッシュ(会員登録)
const hash = await bcrypt.hash(password, 12); // cost 12

// 検証(ログイン)
const isValid = await bcrypt.compare(inputPassword, storedHash);
# Python with bcrypt
import bcrypt

# ハッシュ
hashed = bcrypt.hashpw(password.encode(), bcrypt.gensalt(rounds=12))

# 検証
is_valid = bcrypt.checkpw(input_password.encode(), stored_hash)

Argon2:次世代の標準

Argon2とは?

2015年Password Hashing Competitionの優勝者です。OWASPが2026年第1位推奨のアルゴリズムです。

Argon2の変形

変形特徴推奨
Argon2dGPU攻撃耐性サイドチャネル脆弱
Argon2iサイドチャネル耐性GPU攻撃脆弱
Argon2idd + iのハイブリッド✅ 推奨

Argon2のパラメータ

Argon2id(memory, iterations, parallelism, password, salt)

- memory:メモリ使用量(KB)
- iterations:反復回数
- parallelism:並列スレッド数

OWASP推奨設定(2026年)

最小設定:
- memory:64MB(65536 KB)
- iterations:3
- parallelism:4

高セキュリティ:
- memory:256MB
- iterations:4
- parallelism:8

コード例

// Node.js with argon2
const argon2 = require('argon2');

// ハッシュ
const hash = await argon2.hash(password, {
  type: argon2.argon2id,
  memoryCost: 65536, // 64MB
  timeCost: 3,
  parallelism: 4
});

// 検証
const isValid = await argon2.verify(storedHash, inputPassword);
# Python with argon2-cffi
from argon2 import PasswordHasher

ph = PasswordHasher(
    memory_cost=65536,
    time_cost=3,
    parallelism=4
)

# ハッシュ
hash = ph.hash(password)

# 検証
try:
    ph.verify(stored_hash, input_password)
except VerifyMismatchError:
    # パスワード不一致

bcrypt vs Argon2:何を選ぶべきか?

比較表

項目bcryptArgon2id
年齢1999年(27年)2015年(11年)
検証27年の実戦検証学術検証完了
メモリ調整
GPU耐性⚠️ 中程度✅ 強い
ライブラリ全言語対応ほとんどの言語
OWASP推奨第2位第1位

選択ガイド

bcryptを選択

  • レガシーシステムとの互換性が必要
  • 検証された安定性を優先
  • シンプルな設定を好む

Argon2idを選択

  • 新プロジェクトの開始
  • 最新セキュリティ標準に準拠
  • 高いGPU耐性が必要

2026年推奨順位(OWASP)

第1位:Argon2id
第2位:bcrypt
第3位:scrypt
第4位:PBKDF2(互換性が必要な場合)

SHA-256を使用すべき場合

SHA-256はパスワード以外の用途には完璧です。

適切な用途

用途
ファイル整合性ダウンロード検証、バックアップ確認
デジタル署名JWT、証明書
ブロックチェーンビットコインマイニング
チェックサムデータ転送検証
ハッシュテーブル(HMACと共に)APIキー保存

コード例

// ファイルハッシュ(Node.js)
const crypto = require('crypto');
const fs = require('fs');

const fileBuffer = fs.readFileSync('file.zip');
const hash = crypto.createHash('sha256').update(fileBuffer).digest('hex');

console.log(hash); // "a1b2c3d4..."

実践実装チェックリスト

パスワード保存

  • Argon2idまたはbcryptを使用
  • 適切なwork factorを設定(250-500ms)
  • ライブラリの自動salt生成を使用
  • ハッシュ結果全体を保存(salt含む)

パスワード検証

  • タイミング攻撃防止の比較関数を使用
  • 検証失敗時に一貫した応答時間
  • ログイン失敗回数の制限

マイグレーション

  • 新しいハッシュへの段階的アップグレード
  • ログイン成功時に新アルゴリズムで再ハッシュ
  • 古いハッシュを識別できるようにprefixを使用

FAQ

Q1:MD5で保存された既存のパスワードはどうすれば良いですか?

A:ユーザーがログインする際に新しいアルゴリズムで再ハッシュしてください。

// ログイン成功時
if (hash.startsWith('$md5$')) {
  // bcryptで再ハッシュ
  const newHash = await bcrypt.hash(inputPassword, 12);
  await updateUserHash(userId, newHash);
}

Q2:bcryptの72バイト制限は問題になりませんか?

A:ほとんどのパスワードは72バイト以内です。より長い入力が必要な場合は、まずSHA-256でハッシュしてからbcryptを適用してください。

// 長いパスワードの処理
const prehash = crypto.createHash('sha256').update(password).digest('base64');
const finalHash = await bcrypt.hash(prehash, 12);

Q3:cost factorを高くしすぎるとDoS攻撃に脆弱になりませんか?

A:その通りです。ログインリクエストのレート制限(rate limiting)も一緒に実装してください。250-500msが適切なバランス点です。

Q4:pepperは必要ですか?

A:pepper(アプリケーションレベルの秘密鍵)は追加のセキュリティを提供しますが、必須ではありません。saltだけでも十分です。

Q5:オンラインハッシュツールを使っても良いですか?

A:学習/テスト目的でのみ使用してください。本番環境ではサーバーサイドでハッシュする必要があります。ハッシュジェネレーターは100%クライアントサイドで処理されるため安全です。


まとめ

用途推奨アルゴリズム
パスワード保存Argon2id > bcrypt
ファイル整合性SHA-256
デジタル署名SHA-256 / SHA-512
レガシー互換bcrypt / PBKDF2

重要原則

  1. パスワードに高速ハッシュ(SHA-256、MD5)は絶対禁止
  2. bcrypt cost 12以上、Argon2 memory 64MB以上
  3. ライブラリ提供のsalt自動生成を使用

関連ツール

ツール用途
Hash GeneratorSHA-256、bcryptハッシュ生成
Password Generator強力なパスワード生成
セキュリティハッシュSHA-256bcryptArgon2暗号化開発

著者について

Toolypet Team

Toolypet Team

Development Team

The Toolypet Team creates free, privacy-focused web tools for developers and designers. All tools run entirely in your browser with no data sent to servers.

Web DevelopmentCSS ToolsDeveloper ToolsSEOSecurity