パスワードハッシュとソルト

EXCEL

パスワードハッシュとソルトの適切な実装と運用は、認証情報保護の基本である。その実践的側面を解説する。

パスワードハッシュとソルト:認証情報保護のための実践的アプローチ

脅威モデル

主要な脅威は、攻撃者によるデータベースからのパスワードハッシュ値の窃取である。窃取されたハッシュ値は、オフライン攻撃(辞書攻撃、ブルートフォース攻撃、レインボーテーブル攻撃)に利用され、元のパスワードが特定されるリスクがある。特定されたパスワードは、対象サービスへの不正ログインだけでなく、他のサービスへのクレデンシャルスタッフィング攻撃にも悪用され、広範囲な被害に繋がる。脅威主体は外部攻撃者や、内部不正者も含まれる。

攻撃シナリオ

攻撃者は、アプリケーションの脆弱性(例:SQLインジェクション、OSコマンドインジェクション)を突いてシステムへ侵入し、データベースに保存されたユーザー認証情報(ハッシュ化されたパスワードとソルト)を窃取する。

攻撃者は窃取したハッシュ値を分析し、ハッシュアルゴリズムの種類、ソルトの有無や長さ、イテレーション回数などのパラメータを確認する。 ソルトが欠如している場合や、固定ソルトが使用されている場合は、事前に計算されたレインボーテーブルを用いて効率的にパスワードを特定する。 MD5やSHA1のような旧式の高速なハッシュ関数が使用されている場合、大量のGPUリソースを用いて辞書攻撃やブルートフォース攻撃を短時間で実行し、パスワードをクラックする。 クラックされたパスワードは、他のアカウントへのログイン試行や個人情報詐取に利用される。

graph TD
    A["外部攻撃者"] --> B{"アプリケーション脆弱性悪用"};
    B --> C["DBへの不正アクセス"];
    C --> D["ハッシュ化されたパスワードとソルト窃取"];
    D --> E{"オフラインクラック"};
    E -- ソルトなし/固定 --> F["レインボーテーブル攻撃"];
    E -- 弱いハッシュ/低コスト --> G["辞書攻撃/ブルートフォース攻撃"];
    F --> H["パスワード特定"];
    G --> H["パスワード特定"];
    H --> I["ユーザーアカウント乗っ取り"];
    I --> J["クレデンシャルスタッフィング攻撃/情報漏洩"];

検出/緩和

緩和策:安全なパスワードハッシュ実装

安全なパスワードハッシュには、計算に時間とリソースを要する「パスワードベースの鍵導出関数 (PBKDF)」を使用する。これにより、攻撃者がオフラインでパスワードをクラックする際のコストを大幅に増加させる。

誤用例:MD5/SHA1 (非推奨) MD5やSHA1は暗号学的ハッシュ関数ではあるが、パスワードハッシュには不適切である。高速であるためブルートフォース攻撃に弱く、衝突攻撃のリスクも存在する。

# MD5の例(bash)
echo -n "password123" | openssl md5
# -> (stdin)= a06c27183e878508a8d11b31a31b402e

# SHA1の例(python)
python -c "import hashlib; print(hashlib.sha1(b'password123').hexdigest())"
# -> 40bd001563085fc35165329ea1ff5c5ecbdbbeef

これらのハッシュは、個別のランダムソルトを使用しても依然として高速であるため、ブルートフォース攻撃に対する耐性が低い。

安全な代替:PBKDF2, Bcrypt, Argon2 (推奨) NIST SP 800-63Bは、PBKDF2, Bcrypt, Argon2の使用を推奨している。これらはストレッチング(イテレーション回数)やメモリコストを調整可能であり、オフライン攻撃への耐性を高める。各ユーザーごとにユニークなランダムソルトを生成し、ハッシュ値とともに保存することが必須である。

# PythonでのBcrypt実装例 (passlibライブラリ使用)
from passlib.hash import bcrypt

# パスワードをハッシュ化
password = "supersecretpassword"
hashed_password = bcrypt.hash(password, rounds=12) # roundsはイテレーション回数。高いほど安全だが処理が重くなる
print(f"Hashed Password (Bcrypt): {hashed_password}")

# パスワード検証
is_valid = bcrypt.verify(password, hashed_password)
print(f"Password Valid: {is_valid}")

# PythonでのArgon2実装例 (passlibライブラリ使用)
from passlib.hash import argon2

hashed_password_argon2 = argon2.hash(password, time_cost=3, memory_cost=65536, parallelism=4)
print(f"Hashed Password (Argon2): {hashed_password_argon2}")
is_valid_argon2 = argon2.verify(password, hashed_password_argon2)
print(f"Password Valid (Argon2): {is_valid_argon2}")

rounds, time_cost, memory_cost, parallelism などのパラメータは、システムのCPU/メモリリソースとセキュリティ要求のバランスを考慮して決定する。

検出策

  • データベースアクセス監視: データベース監査ログやSIEM連携により、不正なDBクエリ、異常なアクセス元IP、大量のデータ取得など、異常なDBアクセスパターンをリアルタイムで監視する。
  • WAFログ分析: SQLインジェクションなどのWebアプリケーション攻撃試行を検出し、その後の挙動と紐付けて分析する。
  • 認証ログ監視: 不正ログイン試行、アカウントロックアウト、特権ユーザーの認証、ログイン元IPアドレスの異常な変化などを監視する。
  • ユーザー行動分析 (UEBA): ユーザーの通常の行動パターンからの逸脱を検出し、アカウント乗っ取りの兆候を早期に捉える。

運用対策

鍵/秘匿情報の取り扱い

  • ソルトの管理: 各ユーザーのパスワードハッシュには、最低16バイト(128ビット)以上のランダムなソルトを生成し、ハッシュ値とともにデータベースに保存する。ソルト自体は秘匿情報ではないが、ユニークであることに意味がある。
  • KMSの利用: ハッシュ化に必要な鍵(例:HMACベースのPBKDF2におけるHMACキー)や、データベースへの接続文字列などの秘匿情報は、AWS KMS、Azure Key Vault、Google Cloud KMSなどの鍵管理サービス (KMS) を利用して安全に管理する。
  • 鍵のローテーション: KMSに保存された鍵は、定期的なローテーションポリシーを確立し、実施する。これにより、鍵の漏洩時の影響範囲を限定する。
  • 最小権限の原則: データベースへのアクセス権限は、アプリケーションが必要とする最低限の権限に制限する。例えば、パスワードハッシュテーブルに対してはINSERT/SELECT権限のみとし、DELETEやALTER権限は付与しない。

監査と監視

  • 詳細なログ取得: データベースへのすべてのアクセス、認証試行、特権操作、設定変更などについて、詳細なログを取得する。
  • SIEM連携: 取得したログはSIEM (Security Information and Event Management) に集約し、相関分析を通じてセキュリティインシデントの兆候を検出する。
  • 定期的なログレビュー: SIEMのアラートだけでなく、定期的に手動または自動化ツールでログをレビューし、異常な活動がないか確認する。

現場の落とし穴

  • 誤検知と可用性トレードオフ: 不正ログイン試行の検出閾値を厳しく設定しすぎると、正規ユーザーが誤ってロックアウトされ、サービスの可用性を損なう可能性がある。逆に閾値が甘いと、検出遅延や攻撃の見逃しに繋がる。システム特性に応じた適切なバランスを見出すことが重要である。
  • 検出遅延: ログのリアルタイム性、SIEMの処理能力、アラート設定の適切性が確保されていないと、脅威が進行してから検出されるリスクがある。継続的な監視とチューニングが求められる。
  • パフォーマンスとの兼ね合い: 安全なパスワードハッシュアルゴリズムは、意図的に計算コストが高く設定されている。これは認証時のCPUやメモリリソースの消費を増加させ、システム全体のパフォーマンスに影響を与える可能性がある。特に大規模システムでは、適切なコストパラメータ設定に注意が必要である。
  • レガシーシステムとの互換性: 既存のレガシーシステムを新しいハッシュアルゴリズムに移行する際には、ダウンタイムや互換性の問題が発生する可能性がある。段階的な移行計画や、新しいハッシュ方式へのアップグレードを促すための仕組み(例:パスワード更新時にハッシュ再生成)を検討する。

まとめ

パスワードハッシュとソルトの適切な実装は、認証情報保護の根幹をなす。NISTが推奨するPBKDF2, Bcrypt, Argon2などのストレッチング機能を持つPBKDFと、各パスワードにユニークなランダムソルトを組み合わせることが必須である。これに加え、KMSを用いた鍵管理、最小権限の原則に基づくアクセス制御、厳格な監査と継続的な監視によって、多層的なセキュリティ対策を講じる必要がある。システム運用においては、セキュリティと可用性のトレードオフを適切に管理し、現場の落とし穴を回避するための継続的な改善が求められる。

ライセンス:本記事のテキスト/コードは特記なき限り CC BY 4.0 です。引用の際は出典URL(本ページ)を明記してください。
利用ポリシー もご参照ください。

コメント

タイトルとURLをコピーしました