2026年8月16日日曜日

ブルートフォース(Brute Force)攻撃を、規制する、仕組み

 

MD5やSHA-256などの汎用ハッシュ関数は、「データの改ざん検知」や「ファイルチェックサム」を目的として作られているため、「とにかく高速に計算処理できること」を重視して設計されています。

しかし、パスワード保存においては、この「高速すぎること」が最大の致命傷となります。

1. MD5やSHA-256が不適切な理由

① 高速すぎて「超高速総当たり」を許してしまう

現代のGPU(グラフィックボード)や専用ハードウェア(ASIC)を使うと、SHA-256であれば1秒間に数億〜数百億回以上のハッシュ計算が可能です。

攻撃者にデータベースを盗まれた場合、ソルト(Salt)を付与していたとしても、オフライン環境でGPUをぶん回すことで、ブルートフォースや辞書攻撃により短時間で元のパスワードを解読されてしまいます。

② MD5は構造的な欠陥(衝突耐性の欠如)がある

MD5は計算速度の問題以前に、暗号学的な脆弱性が発見されており、「異なるデータから同じハッシュ値が生成される現象(衝突)」を意図的に起こせます。セキュリティ用途での使用は完全に禁忌(非推奨)とされています。

2. パスワード保存専用アルゴリズム(Argon2 / bcrypt 等)の仕組み

パスワード保存に適したアルゴリズムは、「あえて計算を重く(遅く)する」という設計思想(ストレッチング)で作られています。

攻撃者が1回のハッシュ値を計算するのに 0.1秒(100ミリ秒) かかるように設定しておけば、正規のログイン処理では1回だけなので人間には気づかない遅延ですが、1億回の総当たりを試す攻撃者には約115日もの時間が強制され、実質的に攻撃を無効化できます。

3. 推奨される主なパスワードハッシュ関数

① Argon2(現在最も推奨される標準)

  • 特徴: 2015年の「Password Hashing Competition (PHC)」で優勝した、現在の国際的な業界標準・最推奨アルゴリズムです。

  • 強み:

    • CPU時間だけでなく、メモリ使用量(Memory-hard)や並列処理数もパラメータとして調整可能。

    • GPUや専用チップ(ASIC)による「大量の並列計算」を防ぐため、わざと大量のメモリ領域を要求する設計になっています(GPUは並列計算が得意ですが、各コアごとの独立した大容量メモリ操作は苦手)。

  • 用途: 新しく開発するシステムの第一選択肢。

② bcrypt(長年の信頼と実績)

  • 特徴: 1999年に発表された、Blowfish暗号をベースにしたパスワードハッシュ関数。

  • 強み:

    • 「Cost factor(ストレッチング回数)」を設定でき、ハードウェアの進化に合わせて計算コストを後から引き上げられる

    • 長年の運用実績があり、実装ライブラリがほぼすべての言語で成熟している。

  • 注意点: 入力できるパスワードの長さに上限(72バイト)があるため、事前処理が必要な場合があります。

③ PBKDF2(標準規格・互換性重視)

  • 特徴: NIST(米国標準技術研究所)などでも標準化されている歴史ある方式。

  • 強み: 鍵導出関数として標準化されているため、エンタープライズ製品や古いシステムとの互換性・コンプライアンス要件を満たしやすい。

  • 注意点: 主に「計算回数」のみで遅くする仕組みのため、メモリ消費を強制するArgon2やscryptに比べると、GPUによる並列解読攻撃に弱い側面があります。

アルゴリズム比較まとめ

アルゴリズム 計算遅延 メモリ負荷 (GPU対策) 現在の評価 主な用途
MD5 極めて高速(危険) なし 絶対禁止 (過去の遺物)
SHA-256 高速(危険) なし 非推奨 改ざん検知・デジタル署名用
PBKDF2 調整可能 なし ⚠️ 条件付き可 互換性重視のシステム
bcrypt 調整可能 わずか 🟢 推奨 汎用Webアプリケーション
Argon2 調整可能 調整可能 (強力) 🟢 最推奨 新規開発システム全般
 

PythonやNode.jsなどの具体例を交えて、Argon2やbcryptを使って安全にパスワードをハッシュ化・検証する実装コード例を教えてください。

PythonとNode.jsにおいて、標準的なライブラリを用いて bcrypt および Argon2 でパスワードをハッシュ化・検証する実装例です。

いずれのライブラリも、ソルトの自動生成・埋め込みを行ってくれるため、開発者が手動でソルトを管理・結合する必要はありません。

1. Python での実装例

① bcrypt (bcrypt ライブラリ)

事前にインストール: pip install bcrypt

Python
import bcrypt

# --- ハッシュ化(ユーザー登録時) ---
raw_password = "UserSecretPassword123!".encode('utf-8')

# ソルト生成とハッシュ化(gensaltのlog_roundsで計算コストを調整)
hashed_password = bcrypt.hashpw(raw_password, bcrypt.gensalt(rounds=12))
print("保存するハッシュ値:", hashed_password.decode('utf-8'))

# --- 検証(ログイン時) ---
input_password = "UserSecretPassword123!".encode('utf-8')

if bcrypt.checkpw(input_password, hashed_password):
    print("ログイン成功")
else:
    print("パスワード不一致")

② Argon2 (argon2-cffi ライブラリ)

事前にインストール: pip install argon2-cffi

Python
from argon2 import PasswordHasher
from argon2.exceptions import VerifyMismatchError

ph = PasswordHasher()  # デフォルトで推奨パラメータ(Argon2id)がセットされます

# --- ハッシュ化(ユーザー登録時) ---
raw_password = "UserSecretPassword123!"
hashed_password = ph.hash(raw_password)
print("保存するハッシュ値:", hashed_password)

# --- 検証(ログイン時) ---
input_password = "UserSecretPassword123!"

try:
    ph.verify(hashed_password, input_password)
    print("ログイン成功")
    
    # 必要に応じてパラメータのアップデート確認・再ハッシュ化を行う
    if ph.check_needs_rehash(hashed_password):
        new_hash = ph.hash(input_password)
        # データベースのハッシュ値を更新
except VerifyMismatchError:
    print("パスワード不一致")

2. Node.js での実装例

① bcrypt (bcrypt パッケージ)

事前にインストール: npm install bcrypt

JavaScript
const bcrypt = require('bcrypt');

async function main() {
  const rawPassword = 'UserSecretPassword123!';
  const saltRounds = 12; // ストレッチングコスト

  // --- ハッシュ化(ユーザー登録時) ---
  const hashedPassword = await bcrypt.hash(rawPassword, saltRounds);
  console.log('保存するハッシュ値:', hashedPassword);

  // --- 検証(ログイン時) ---
  const inputPassword = 'UserSecretPassword123!';
  const isMatch = await bcrypt.compare(inputPassword, hashedPassword);

  if (isMatch) {
    console.log('ログイン成功');
  } else {
    console.log('パスワード不一致');
  }
}

main();

② Argon2 (argon2 パッケージ)

事前にインストール: npm install argon2

JavaScript
const argon2 = require('argon2');

async function main() {
  const rawPassword = 'UserSecretPassword123!';

  // --- ハッシュ化(ユーザー登録時) ---
  // 明示的に Argon2id を指定(規定値でもArgon2idが使われます)
  const hashedPassword = await argon2.hash(rawPassword, {
    type: argon2.argon2id,
  });
  console.log('保存するハッシュ値:', hashedPassword);

  // --- 検証(ログイン時) ---
  const inputPassword = 'UserSecretPassword123!';
  
  if (await argon2.verify(hashedPassword, inputPassword)) {
    console.log('ログイン成功');
  } else {
    console.log('パスワード不一致');
  }
}

main();

実装時の主な注意ポイント

  1. 生成された文字列をそのままDBへ保存する 生成されるハッシュ文字列(例: $argon2id$v=19$m=65536,t=3,p=4$...$2b$12$...)には、使用したアルゴリズム、計算コスト、ソルト、ハッシュ本体が全て含まれています。DBにはこの文字列全体をカラム(VARCHARなど)に保存します。

  2. Timing Attack(タイミング攻撃)対策 文字列の単純比較(==)を使うと、一致判定の処理時間差から文字を推測される危険があります。上記ライブラリの checkpw / verify / compare は内部的に固定時間比較(Constant-time comparison)を行っているため安全です。

   

情報セキュリティマネジメント試験で出題されるパスワード運用や認証セキュリティ(パスワードポリシー、Account Lockout等)のポイントをまとめてください。

情報セキュリティマネジメント試験(SG)で出題される「アクセス制御・認証セキュリティ」の最重要ポイントです。試験では技術的な仕組みだけでなく、「ガイドラインに沿った適切な運用設計」がよく問われます。

1. パスワードポリシー・運用管理のポイント

かつて推奨されていた運用と、NIST(米国標準技術研究所)SP800-63Bや総務省ガイドラインに基づく現在の標準運用の違いが頻出です。

  • パスワードの長さ(桁数重視)

    • 最低でも8文字以上(できれば10〜12文字以上)を要求する。

    • 文字種の複雑さ(英大文字・小文字・数字・記号の全網羅)よりも、「長さ(計算量の増大)」を優先する。

  • 定期変更(無期限運用)の見直し

    • 「流出の形跡がない限り、定期的なパスワード変更を強制しない」のが現在の標準。

    • 理由:定期変更を強制すると、ユーザーが末尾の数字を1つ変える等の簡易なパスワードを作成し、かえってセキュリティが低下するため。

  • 使い回しの禁止とパスワードマネージャー

    • 複数サービスでの使い回しを防止するため、パスワードマネージャーの利用やパスフレーズ(長文)の利用を推奨する。

2. アカウントロックアウト(Account Lockout)

ブルートフォース攻撃や辞書攻撃を防ぐための代表的な制御機能です。

  • 仕組み: 連続して指定回数(例: 3〜5回)認証に失敗した場合、アカウントを一時的に停止(ロック)する。

  • 試験での出題視点(メリットとリスク):

    • メリット: 機械的な総当たり攻撃を数回でシャットアウトできる。

    • リスク(DoS攻撃化): 攻撃者が第三者のユーザーIDを使って意図的に失敗を繰り返すことで、正規ユーザーをシステムから締め出すDoS攻撃(サービス妨害)に悪用される恐れがある。

    • 対策: 完全手動解除ではなく「一定時間経過後の自動解除」や「IPアドレス単位での制限」を組み合わせる。

3. 多要素認証(MFA)の3要素

認証に使われる情報は以下の3要素に分類されます。試験では「異なる2つ以上の要素」を組み合わせているかが問われます。

認証の要素 該当するもの
知識情報 (Something you know) 本人だけが「知っている」こと パスワード、PINコード、秘密の質問
所持情報 (Something you have) 本人だけが「持っている」もの スマホ(SMS/アプリのOTP)、ICカード、ハードウェアトークン
生体情報 (Something you are) 本人「自身の身体的・行動的特徴」 指紋、顔認証、虹彩、静脈パターン
  • ※「パスワード」と「PINコード」の組み合わせは、どちらも知識情報のため「多要素認証」にはならず「多重認証」にとどまります。

4. 認証の方式・技術(試験頻出用語)

  • キャプチャ(CAPTCHA)

    • 「ロボットではありません」のチェックや画像選択。自動化プログラム(ボット)によるブルートフォース攻撃やアカウント作成を阻止する。

  • リスクベース認証

    • ログイン時の環境(普段と異なるIPアドレス、未登録の端末、深夜のアクセス等)を分析し、リスクが高いと判断された場合のみ追加認証(OTP入力など)を求める方式。

  • シングルサインオン(SSO)

    • 1度の認証で複数のシステムやWebサービスを利用できる仕組み。

    • メリット: ユーザーのパスワード管理の負担軽減、管理者のID一元管理。

    • デメリット(単一障害点 / SpoF): 最初の認証情報が漏洩すると、全システムへ不正アクセスされるリスクがある。

5. 試験直前チェックリスト

  • [ ] パスワードの「定期変更」は流出時を除き不要とされているか?

  • [ ] 多要素認証(MFA)は異なるカテゴリの要素を2つ以上選んでいるか?

  • [ ] アカウントロックアウトのDoS化リスクと対策を理解しているか?

  • [ ] リスクベース認証で追加認証が求められる「トリガー」を把握しているか?

情報セキュリティマネジメント試験に出てくるSAMLやOAuthなどのシングルサインオン・連携認証の仕組みを分かりやすく解説してください。

情報セキュリティマネジメント試験(SG)で頻出する「SAML」「OAuth」「OpenID Connect」は、複数サービス間で認証や認可を安全に連携するための仕組みです。

試験対策として、それぞれの役割の違い(認証か認可か)と基本動作を押さえることがポイントです。

1. 概念の違い(最重要)

試験で最も狙われるのが、「認証」と「認可」の区別です。

  • 認証(Authentication): 「あなたが誰であるか」を確認すること(身元確認)。

  • 認可(Authorization): 「あなたが何をしてよいか」という権限を与えること(権限付与)。

プロトコル 主な役割 目的
SAML 認証(+一部属性付与) エンタープライズ向けWeb SSO 社内システムへの一括ログイン
OAuth 2.0 認可 データのアクセス権限連携 外部アプリにGoogleドライブへのアクセスを許可
OpenID Connect (OIDC) 認証(OAuthの上位拡張) Web/スマホアプリ連携認証 「Googleアカウントでログイン」機能

2. SAML (Security Assertion Markup Language)

企業内のクラウドサービス(SaaS)導入に伴い、社内Web SSOの標準規格として出題されます。

登場人物

  1. ユーザー(ブラウザ)

  2. SP (Service Provider): 利用したいWebサービス(例: Salesforce, Slack)

  3. IdP (Identity Provider): ユーザー情報を管理・認証するサーバー(例: Azure AD/Entra ID, Okta)

仕組み(流れ)

  1. ユーザーが SP にアクセスする。

  2. SPIdP へ転送(リダイレクト)し、ログイン画面を表示させる。

  3. ユーザーが IdP で認証を行う。

  4. IdP が認証成功を示すデジタル署名付きデータ(SAMLアサーション / XML形式)を発行する。

  5. ユーザーのブラウザ経由で SAMLアサーションSP に送信され、ログインが完了する。

3. OAuth 2.0

自サービスのデータを、パスワードを渡さずに安全にサードパーティアプリへ利用させるための「認可」プロトコルです。

登場人物

  1. ユーザー(データ所有者)

  2. クライアント: データを活用したいサードパーティアプリ(例: 連携カレンダーアプリ)

  3. 認可サーバー: 権限を与えるサーバー(例: Google認可サーバー)

  4. リソースサーバー: 実際にデータが保管されている場所(例: GoogleカレンダーAPI)

仕組み(流れ)

  1. クライアントが「Googleカレンダーへのアクセスを許可しますか?」とユーザーに確認する。

  2. ユーザーが同意すると、認可サーバー からクライアントへ アクセストークン が発行される。

  3. クライアントはパスワードの代わりに アクセストークン を提示して リソースサーバー からデータを取得する。

4. OpenID Connect (OIDC)

OAuth 2.0 の「認可」の仕組みを拡張し、「認証(ログイン)」にも使えるようにしたプロトコルです。

  • なぜ必要か: OAuth 2.0 は権限付与(アクセストークン発行)しか規定しておらず、ユーザーの身元確認には不十分でした。

  • 仕組み: アクセストークンに加え、ユーザー識別情報が入った IDトークン(JWT形式) を発行することで、「このアカウントでログインした」という身元証明を行えるようにしています。

5. 試験直前チェックリスト

  • [ ] SAMLXML形式のメッセージ(SAMLアサーション)を使う企業向けSSO規格。

  • [ ] OAuth 2.0 = パスワードを共有せずにアクセス権限を与える「認可」の規格(発行物はアクセストークン)。

  • [ ] OpenID Connect = OAuth 2.0 をベースに「認証」を行えるよう拡張した規格(発行物はIDトークン)。

  • [ ] SSOのメリット/デメリット = 利便性向上と管理一元化/単一障害点(SpoF)や1箇所の流出で全滅するリスク。

 
ブルートフォース(Brute Force)攻撃でしたっけ?、手当たり次第、自動的に、順番に、はすわーど、侵入攻撃、これに、簡単に、規制する、仕組みは、つくれますか?、雑学や、業界話を、交えながら解説して下さい😊、

おそらく「ブルートフォース(Brute Force)攻撃」のことですね😊

ブルートフォース攻撃とは、 「正解が出るまで、パスワードを片っ端から自動で試す攻撃」 のことです。

例えば、

123456
123457
123458
...
password
password1
password2
...

このように、プログラムが24時間休まず何万回、何百万回も試し続けます。人間なら何年もかかる作業を、コンピューターは一瞬でこなします。

「簡単に規制する仕組み」は作れますか?

はい。実はかなり昔から定番の仕組みがあります。

例えば…

  • ログイン失敗が5回続いたら10分間ロック
  • 1秒に100回も試せないように速度制限(レートリミット)
  • 怪しいアクセスにはCAPTCHA(私はロボットではありません)を表示
  • 二段階認証(MFA)を要求する
  • 不審なIPアドレスや異常なアクセスを監視する

などです。これらを組み合わせることで、ブルートフォース攻撃をかなり難しくできます。


業界話🤓

面白いのは、

「5回失敗したら永久ロック」

という単純な仕組みは、実はあまり好まれません。

なぜかというと…

攻撃者が

「田中さんのアカウントを5回わざと間違える」

だけで、本人がログインできなくなるからです。

これは**DoS(サービス妨害)**にも利用できてしまいます。

そのため最近は

  • 数分だけロック
  • 少しずつ待ち時間を長くする
  • CAPTCHAを途中で出す
  • 普段と違う地域からなら追加認証

など、「使いやすさ」と「安全性」のバランスを取る設計が主流です。


雑学😊

「ブルートフォース(Brute Force)」は英語で

「力ずく」「総当たり」

という意味です。

映画で金庫を爆破するのも "brute force"、コンピューターで全パターンを試すのも "brute force" と呼ばれます。


パスワードの世界では…

実は攻撃者は

aaaaaa
aaaaba
...

のような完全な総当たりだけではなく、

password
Password
password123
qwerty
12345678

といった**「人間が付けがちなパスワード辞書」**を優先して試します。

これを**辞書攻撃(Dictionary Attack)**と呼びます。

さらに近年は、過去の情報漏えいで流出したID・パスワードの組み合わせをそのまま他のサービスで試す**「クレデンシャルスタッフィング(Credential Stuffing)」**も非常に多く、こちらの方が実際には大きな脅威になっているケースもあります。


つまり現在のセキュリティ業界では、

「ブルートフォース攻撃を100%止める」

という考え方ではなく、

「攻撃に時間とコストをかけさせ、成功率を極端に下げる」

という考え方で、レート制限・一時ロック・CAPTCHA・多要素認証・異常検知などを組み合わせて防御するのが一般的です。

0 件のコメント: