パスワードエントロピー:パスワード強度を測定し最大化する方法
「強いパスワード」には大文字、数字、特殊文字が必要だと言われたことがあるでしょう。しかし P@$$w0rd! はこれらのルールをすべて満たしていますが、1秒以内にクラックされます。
パスワード強度の真の尺度は使用する文字の種類ではありません。それはエントロピーです。情報理論の概念で、パスワードの予測不可能性を定量化するものです。
このガイドでは、パスワードエントロピーの仕組み、計算方法、そして本当にクラックしにくいパスワードの生成方法を詳しく解説します。
パスワードエントロピーとは?
パスワードエントロピーは、パスワードの予測不可能性をビット単位で測定します。エントロピーが1ビット増えるごとに、攻撃者がブルートフォースでクラックするのに必要な試行回数が2倍になります。
サイコロで例えると分かりやすいでしょう。6面サイコロは1回の投げで約2.6ビットのエントロピーがあります。6通りの結果しかないからです。20面サイコロは約4.3ビットです。面が多いほど不確実性が高くなります。
パスワードも同じ原理です。使える文字が多いほど(サイコロの面が多い)、パスワードが長いほど(投げる回数が多い)、エントロピーは高くなります。
これが、エントロピーが複雑さのルールより科学的な理由です。複雑に見えるパスワード(Tr0ub4dor&3)でも、予測可能なパターンに従っていればエントロピーは低くなります。一方、シンプルに見えるパスフレーズ(correct horse battery staple)は、大きな候補プールからランダムに選ばれているため、高いエントロピーを持つことができます。
計算式:パスワードエントロピーの計算方法
計算式はシンプルです:
E = L × log₂(R)
ここで:
- E = エントロピー(ビット)
- L = パスワードの長さ(文字数)
- R = プールサイズ(各位置で使える文字数)
文字プールサイズ一覧
| 文字タイプ | プールサイズ (R) | 1文字あたりのビット |
|---|---|---|
| 小文字のみ (a-z) | 26 | 4.70 |
| 小文字 + 数字 | 36 | 5.17 |
| 大小文字 + 数字 | 62 | 5.95 |
| 印刷可能ASCII全体 | 94 | 6.55 |
| Diceware 単語リスト | 7,776 | 1単語あたり 12.92 |
コードで計算する
// Calculate password entropy in JavaScript
const entropy = (length, poolSize) =>
length * Math.log2(poolSize);
entropy(8, 26); // → 37.60 bits (lowercase only)
entropy(12, 62); // → 71.45 bits (alphanumeric)
entropy(16, 94); // → 104.87 bits (full charset)
import math
def entropy(length: int, pool_size: int) -> float:
return length * math.log2(pool_size)
entropy(8, 26) # → 37.60 bits
entropy(12, 62) # → 71.45 bits
entropy(16, 94) # → 104.87 bits
重要:この計算式は、各文字が均一にランダムに選ばれることを前提としています。人間がパターンや辞書の単語を使ってパスワードを選ぶ場合、実際のエントロピーは理論上の最大値をはるかに下回ります。
どのくらいのエントロピーがあれば十分か?
答えは、何を保護するか、そして攻撃者の推測速度に依存します。
現代のGPUは、MD5のような高速アルゴリズムに対して毎秒10¹²(1兆)以上のハッシュをテストできます。実際にどういう意味を持つか見てみましょう:
| エントロピー(ビット) | 強度 | クラック時間(10¹²回/秒) | 推奨用途 |
|---|---|---|---|
| < 40 | 弱い | 1秒未満 | 使用不可 |
| 40–59 | 普通 | 秒〜時間 | 使い捨てアカウント |
| 60–79 | 強い | 日〜数百年 | 通常のアカウント |
| 80–99 | 非常に強い | 千年以上 | メール、銀行 |
| 100+ | 極めて強い | 宇宙の熱的死を超える時間 | 暗号鍵、マスターパスワード |
印刷可能ASCII全体を使った16文字のパスワードは約105ビットのエントロピーがあり、「極めて強い」範囲に余裕で入ります。ランダムパスワードジェネレーターを使えば即座に生成でき、各パスワードのエントロピー分析をリアルタイムで確認できます。
NISTの見解(2024年更新)
NIST SP 800-63Bは2024年に大幅な変更を行いました:
- 必須の複雑さルールを廃止(特殊文字の強制なし)
- 定期的なパスワード変更の強制を廃止
- 最低文字数を15文字に引き上げ(従来の8文字から)
- 既知の漏洩パスワードとの照合を重視
- 複雑さよりも長さとランダム性を優先
これらの変更は、エントロピーの数学が常に示してきたことを裏付けています:長さとランダム性は文字の種類よりも重要です。
なぜ長さが複雑さに勝るのか
計算を見てみましょう。12文字のパスワードのエントロピーを上げる2つの方法を比較します:
方法A — 12文字のまま、英数字(62)からASCII全体(94)に変更:
- 12 × log₂(94) - 12 × log₂(62) = 78.66 - 71.45 = +7.21ビット
方法B — 英数字(62)のまま、1文字追加(12→13):
- 13 × log₂(62) - 12 × log₂(62) = 77.40 - 71.45 = +5.95ビット
1文字追加するだけで、文字セットを大幅に変更するのとほぼ同じエントロピーの増加が得られます。2文字追加すれば超えます。
P@$$w0rd!(9文字)を考えてみましょう。ASCII全体を使っていますが短すぎます。さらに悪いことに、辞書攻撃がすでにカバーしている予測可能な「リートスピーク」パターンに従っているため、実効的なエントロピーは理論上の59ビットをはるかに下回ります。
結論:真にランダムなパスワードでは、長さを増やす方が文字の種類を増やすより効率的です。しかし本当の敵は予測可能性であり、短さではありません。
パスフレーズ vs ランダムパスワード
| 比較項目 | ランダムパスワード | パスフレーズ(Diceware) |
|---|---|---|
| 例 | kX#9mP$2vL!nQ7wR | correct horse battery staple |
| 単位あたりのビット | 6.55/文字 | 12.92/単語 |
| 約78ビットに必要な長さ | 12文字 | 6単語 |
| 記憶しやすさ | 難しい | 容易 |
| モバイル入力 | 困難 | 容易 |
| 最適な用途 | パスワードマネージャーの項目 | マスターパスワード、記憶が必要なログイン |
Dicewareの仕組み
Dicewareは7,776語のリスト(6⁵ = 7,776)を使います。5つのサイコロを振って各単語を選び、1単語あたり正確に12.92ビットのエントロピーを得ます。
4単語で約51ビット、6単語で約77ビットです。
どちらを使うべきか?
- パスワードマネージャーに保存するパスワード:16文字以上のフルキャラクターセットのランダムパスワードを使用。手動で入力することはないので記憶性は不要です。ランダムパスワードジェネレーターなら一度に最大50個を一括生成できます。
- マスターパスワード:5-6単語のDicewareパスフレーズを使用。毎日入力できる程度に記憶しやすく、64-77ビットのエントロピーを確保できます。
- APIキーやトークン:
openssl randやcrypto.randomBytes()を使って、人間の記憶を考慮せずに最大エントロピーを確保。
実践:開発者ツールとコード
開発者が高エントロピーの秘密鍵を生成する一般的な方法を紹介します:
ブラウザ(Web Crypto API)
// Cryptographically secure password generation
function generatePassword(length, charset) {
const array = new Uint32Array(length);
crypto.getRandomValues(array);
return Array.from(array, v => charset[v % charset.length]).join('');
}
const chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789!@#$%^&*';
generatePassword(16, chars);
// → 'kX#9mP$2vL!nQ7wR' (random each time)
Node.js
const crypto = require('crypto');
const token = crypto.randomBytes(32).toString('base64url');
// → 'Ql2Hj8xK9mNp3rVw5tYz7uBa0cEf4gIk' (43 chars, 256 bits)
Python
import secrets
token = secrets.token_urlsafe(32) # 256 bits of entropy
password = secrets.token_hex(16) # 128 bits, hex format
コマンドライン
# 192 bits of entropy, base64 encoded
openssl rand -base64 24
# 256 bits, hex encoded
openssl rand -hex 32
方法別エントロピー比較
| 方法 | 出力長 | エントロピー(ビット) |
|---|---|---|
| UUID v4 | 36文字 | 122 |
openssl rand -base64 24 | 32文字 | 192 |
| 16文字フルASCII | 16文字 | 105 |
| 6単語Diceware | 約30文字 | 78 |
| 4単語Diceware | 約20文字 | 52 |
Math.random()をセキュリティ関連で絶対に使わないでください。非暗号学的PRNGを使用しており、攻撃者がシードを知っていれば出力は予測可能です。ブラウザではcrypto.getRandomValues()、Node.jsではcrypto.randomBytes()を必ず使用してください。
パスワードストレージ:エントロピーだけでは不十分な理由
128ビットのパスワードでも、サーバーがMD5のプレーンハッシュで保存していれば無意味です。データベースが漏洩すると、攻撃者は単一のGPUで毎秒数十億のMD5ハッシュをテストできます。
ここで低速ハッシュアルゴリズムが重要になります。各推測を意図的にコストの高い処理にします:
| アルゴリズム | GPU上の速度 | 実効的な減速 |
|---|---|---|
| MD5 | 約100億回/秒 | 基準値(使用禁止) |
| SHA-256 | 約50億回/秒 | 約2倍 |
| bcrypt (cost=12) | 約5回/秒 | 約20億倍 |
| argon2id | 約2回/秒 | 約50億倍 |
bcryptのcostパラメーターは特に優れた設計です:1増えるごとに必要な計算量が2倍になります。cost=12は2¹² = 4,096ラウンドのハッシュ計算を意味し、パスワード自体のエントロピーに加えて12ビットの「ストレージエントロピー」を追加する効果があります。
二重保護モデル:高エントロピーのパスワードはオフラインブルートフォースから保護し、低速ハッシュはデータベース漏洩から保護します。両方が必要です。
ハッシュアルゴリズムの詳細については、MD5とSHA-256の比較をご覧いただき、MD5ハッシュジェネレーターで異なるアルゴリズムの出力を体験してください。
よくあるパスワードの誤解
「90日ごとにパスワードを変更する」
NISTの2024年ガイドラインは、定期的な強制変更を明確に推奨していません。頻繁なローテーションは、ユーザーがより弱く予測可能なパスワードを選ぶ原因になります。パスワードの漏洩が疑われる場合にのみ変更してください。
「a→@、e→3 で強くなる」
リートスピーク置換は、辞書攻撃が最初にチェックするパターンの一つです。password の a を @ に置き換えても、攻撃者はそれを想定しているため、エントロピーはほとんど増えません。
エントロピーを増やすのは、巧みな置換ではなく真のランダム性です。
「8文字に記号を入れれば十分」
94文字のASCIIセット全体を使っても、8文字ではわずか52ビットのエントロピーしかありません。10¹²回/秒の推測速度では、約75分でクラックされます。
最低12文字、重要なアカウントには16文字以上を使用してください。
「複雑に見えるほど安全」
視覚的な複雑さとエントロピーは別物です。Tr0ub4dor&3 は複雑に見えますが、予測可能なパターンに従っています。mfYq8kL2nR はシンプルに見えますが、真にランダムなため、より高いエントロピーを持っています。
包括的なセキュリティ戦略については、Webセキュリティの基本をご覧ください。
よくある質問
何ビットのエントロピーがあれば安全ですか?
ほとんどのオンラインアカウントでは、60-80ビットで強力な保護が得られます。マスターパスワードや暗号鍵などの高価値ターゲットには100ビット以上を目指してください。1ビット追加するごとに、攻撃者に必要な努力が2倍になります。
特殊文字を追加すると常にエントロピーが上がりますか?
文字がプール全体からランダムに選ばれる場合のみです。@ を a の代わりに使うなどの予測可能な置換は、攻撃者が辞書にすでに含めているため、ほとんどエントロピーを追加しません。
4単語のDicewareパスフレーズのエントロピーはどのくらいですか?
標準の7,776語Dicewareリストでは、各単語が12.92ビットを貢献します。4単語で約51.7ビットです。低セキュリティ用途には十分ですが、重要なアカウントには5-6単語(64-78ビット)を使用してください。
Math.random() はパスワード生成に安全ですか?
いいえ。Math.random() は暗号学的に安全でない擬似乱数生成器です。セキュリティに関わる乱数生成には、ブラウザでは crypto.getRandomValues()、Node.jsでは crypto.randomBytes() を使用してください。
bcryptのcostファクターはセキュリティにどう影響しますか?
bcryptのcostファクターが1増えるごとに、ハッシュ計算(つまりブルートフォース攻撃)に必要な計算量が2倍になります。cost=12は2¹² = 4,096回の反復を意味し、パスワード固有のエントロピーに加えて12ビットの難易度を追加する効果があります。
NISTの2024年パスワードガイドラインで何が変わりましたか?
NIST SP 800-63Bは、必須の複雑さ要件(特殊文字の強制、大小文字の混合)と定期的なパスワードローテーションを廃止しました。新しいガイダンスは、より長いパスワード(15文字以上を推奨)、漏洩パスワードデータベースとの照合、スペースを含むすべての印刷可能文字の許可を推進しています。
要点まとめ
- エントロピー = L × log₂(R) — 1ビット増えるごとに必要な推測回数が2倍に
- 長さ > 複雑さ — 1文字追加する方が文字セットを広げるより効果的
- 暗号APIを使用 —
crypto.getRandomValues()かcrypto.randomBytes()、Math.random()は絶対に使わない - パスワードマネージャー + ランダム生成がほとんどの人にとってのベストプラクティス
- サーバー側も重要 — bcryptかargon2を使用、MD5でのパスワード保存は厳禁
高エントロピーのパスワードを生成しませんか?ランダムパスワードジェネレーターをお試しください。作成するすべてのパスワードのエントロピー分析をリアルタイムで表示します。