はじめに:なぜ今でもパスワードが重要なのか
1960年代のタイムシェアリング・コンピュータシステムの黎明期から、パスワードはユーザーとデータの間の主要な門番であり続けてきました。1961年、MITの研究者フェルナンド・コルバトは、互換タイムシェアリングシステム(CTSS)にパスワードを導入しました。これは当初、セキュリティ対策としてではなく、単に各ユーザーにプライベートなファイルスペースを提供するためのものでした。60年以上経った今でも、パスワードはインターネット上で最も普及している認証メカニズムであり、メールアカウントから銀行システムまであらゆるものを保護しています。
しかし、平均的なユーザーは数十のサイトでパスワードを使い回し、Summer2024! のような予測可能なパターンを選択し、何が本当に推測されにくいパスワードなのかについての直感を持っていません。この記事では、パスワードセキュリティについて技術的に深く掘り下げます。エントロピーはどのように計算されるのか、なぜランダム性が重要なのか、最新のガイドラインは何と言っているのか、そして実際にあなたを守る習慣をどのように身につけるべきかについて解説します。
エントロピーの理解:予測不能性の数学
情報理論における エントロピー (Entropy) は、予測不能性を測定します。パスワードにおけるエントロピーは、「攻撃者がこのパスワードを解読するために、平均して何回の試行が必要か」という問いに答えるものです。
公式は以下の通りです:
H = L × log₂(N)
ここで:
- H = ビット単位のエントロピー
- L = パスワードの長さ(文字数)
- N = 文字セットのサイズ(使用可能な文字の種類)
文字セットのサイズ
| 文字セット | サイズ (N) | 1文字あたりのビット数 |
|---|---|---|
| 小文字のみ | 26 | 4.7 bits |
| 小文字 + 大文字 | 52 | 5.7 bits |
| 英数字 | 62 | 5.95 bits |
| 全印刷可能 ASCII | 94 | 6.55 bits |
| 拡張 ASCII / Unicode | 128+ | 7+ bits |
エントロピーの例
| パスワード | L | N | エントロピー (H) |
|---|---|---|---|
password |
8 | 26 | 37.6 bits |
P@ssw0rd |
8 | 94 | 52.4 bits |
k9$mQzLw |
8 | 94 | 52.4 bits |
xK#7pL!qR2@v |
12 | 94 | 78.6 bits |
correct horse battery staple |
28 | 26 | 131.9 bits |
128ビット以上のエントロピーを持つパスワードは、現在の技術では総当たり攻撃(ブルートフォース)が計算上不可能であると見なされています。参考までに、解読不能とされる256ビットAES暗号は、2²⁵⁶通りの鍵空間に対応しています。
CSPRNG vs Math.random():なぜ乱数生成源が重要なのか
すべての乱数が等しく作られているわけではありません。安全なパスワード生成器と不安全なものの違いは、多くの場合、乱数生成源 (Source of Randomness) にあります。
Math.random() —— セキュリティには不適
JavaScriptに組み込まれている Math.random() は、疑似乱数生成器 (PRNG) です。高速で統計的に均一ですが、暗号学的に安全ではありません。その内部状態は出力から推測可能であり、十分な数の値を観察した攻撃者は将来の値を予測できてしまいます。
// ❌ 不安全 —— パスワード生成に使用しないでください
function insecurePassword(length) {
const chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
return Array.from({ length }, () => chars[Math.floor(Math.random() * chars.length)]).join('');
}
crypto.getRandomValues() —— 正しいツール
Web Cryptography APIは crypto.getRandomValues() を提供しており、これはオペレーティングシステムの 暗号学的に安全な疑似乱数生成器 (CSPRNG) からエントロピーを取得します。Linuxでは /dev/urandom、Windowsでは CryptGenRandom がこれに当たります。これらのソースは、ハードウェアイベント(キーストローク、ディスクI/O、ネットワークタイミングなど)からエントロピーを収集し、暗号学的に強力であると見なされています。
// ✅ 安全 —— CSPRNGを使用
function generatePassword(length, charset) {
const array = new Uint32Array(length);
crypto.getRandomValues(array);
return Array.from(array, (val) => charset[val % charset.length]).join('');
}
const charset =
'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789!@#$%^&*()_+-=[]{}|;:,.<>?';
console.log(generatePassword(16, charset));
// 出力例: "aK7!xQz2#Lp9@Wm5"
剰余バイアス(Modulo Bias)に関する注意:
charset.lengthが 2³² を割り切れない場合、上記の例にはわずかな剰余バイアスが生じます。プロダクションコードでは、棄却サンプリング(Rejection Sampling)を使用してこのバイアスを完全に排除すべきです。
文字セットと複雑さ
ほとんどのパスワード生成器では、以下の切り替えが可能です:
- 小文字 (a–z): 26文字
- 大文字 (A–Z): 26文字
- 数字 (0–9): 10文字
- 記号 (!@#$%^&*…): 約32文字
これら4つをすべて組み合わせると、94文字の印刷可能ASCII文字 のプールになります。パスワードに文字を1つ追加するごとに、探索空間は94倍になります。94文字からなる12文字のパスワードは、94¹² ≒ 4.76 × 10²³ 通りの組み合わせがあり、専用ハードウェアにとっても天文学的な数字です。
なぜ複雑さより長さが重要なのか
多くの古いシステムでは「大文字、数字、記号をそれぞれ少なくとも1つ含む」ことが要求されていましたが、8文字のパスワードが許容されていました。94文字セットによる8文字のパスワードは、わずか 94⁸ ≒ 6 × 10¹⁵ 通りの組み合わせしかなく、現代のGPUクラスターを使えば数時間で解読可能です。一方、純粋な小文字のみの16文字パスワード(26¹⁶ ≒ 4.4 × 10²²)は、8文字の複雑なパスワードよりも はるかに多い エントロピーを提供します。
NIST SP 800-63B:現代のパスワードガイドライン
米国国立標準技術研究所の NIST Special Publication 800-63B(電子認証に関するガイドライン、2017年発表、2024年更新)は、パスワードに関する多くの常識を覆しました:
現在のNISTの推奨事項
- ユーザーが選択するパスワードは最低8文字、機械が生成するパスワードは最低15文字 とする。
- 複雑さよりも長さを優先する —— 強制的な複雑さのルール(大文字+数字+記号)は、セキュリティを実質的に向上させず、ユーザーを苛立たせるだけである。
- 漏洩リストと照合する —— 既知のデータ漏洩で見つかったパスワードを拒否する(例:HaveIBeenPwned APIを使用)。
- 妥協の証拠がない限り、定期的な強制変更を行わない —— 強制的な変更は、
Summer2024→Autumn2024のような予測可能なパターンを招く。 - 構成ルールを設けない —— 特定の文字種を要求せず、スペースを含むすべての印刷可能文字を許可する。
- レート制限とロックアウト を行い、オンライン攻撃を防ぐ。
これらのガイドラインは、複雑さの制約下にある人間の行動は予測可能であるという現実を反映しています。記号の要件を満たすために末尾に ! を付けたり、最初の1文字だけを大文字にしたり、覚えやすい西暦を使ったりする傾向があります。
パスワードマネージャー:現実的な解決策
ほとんどの人が行える最大のセキュリティ向上は、パスワードマネージャー を導入することです。パスワードマネージャーは以下のことを行います:
- すべてのアカウントに対して、強力で固有のパスワードを生成する
- それらを暗号化された保管庫(通常はAES-256)に保存する
- ブラウザやアプリで資格情報を自動入力する
- 使い回されているパスワードや漏洩したパスワードを警告する
人気のパスワードマネージャー
| ツール | タイプ | 特徴 |
|---|---|---|
| Bitwarden | オープンソース、クラウド/セルフホスト | 無料枠が充実、監査済み |
| 1Password | 商用、クラウド | トラベルモード、ファミリープラン |
| KeePass | オープンソース、ローカル | 完全オフライン、プラグインが豊富 |
| KeePassXC | オープンソース、ローカル | クロスプラットフォームのKeePassフォーク |
| Dashlane | 商用、クラウド | ダークウェブ・モニタリング |
パスワードマネージャーのマスターパスワードは、長く覚えやすいパスフレーズにすべきです。これこそが、あなたが記憶すべき唯一のパスワードです。
パスフレーズとDicewareメソッド
覚える必要があるパスワード(パスワードマネージャーのマスターパスワードなど)については、複雑な短い文字列よりも パスフレーズ がはるかに優れています。
Dicewareの仕組み
1995年にアーノルド・ラインホルトによって考案されたDicewareメソッドは、物理的なサイコロを使用して真にランダムな単語の選択を行います:
- EFF Large Wordlist(7,776語、11111〜66666の6進数インデックス)を入手する。
- 5つのサイコロ を振り、5桁の数字を得る(例:2-4-1-3-6 → 24136)。
- 対応する単語を調べる(例:「clump」)。
- これを6〜8回繰り返し、パスフレーズを構築する。
7,776語から選ばれた6語のDicewareパスフレーズのエントロピーは:
H = 6 × log₂(7776) = 6 × 12.93 ≒ 77.6 bits
有名な「correct horse battery staple」(XKCD #936)は、約2,000語の一般的な語彙から4つの単語を使用しており、エントロピーは約44ビットです。これは例としては示唆に富みますが、実際には短すぎます。フルDicewareリストから6語以上を使用することが推奨されます。
一般的なパスワード攻撃
攻撃を理解することは、防御を調整するのに役立ちます。
辞書攻撃
攻撃者は、数百万から数十億のエントリを持つワードリストを使用し、ルールベースの変異(最初の文字の大文字化、数字の追加、a を @ に置き換えるなど)と組み合わせます。Hashcatのようなツールは、1秒間に数千の変異ルールを適用できます。辞書の単語に簡単な置換を施しただけのパスワードはすべて脆弱です。
総当たり攻撃(ブルートフォース)
純粋な総当たりは、あらゆる組み合わせを試します。専用のGPUリグ(RTX 4090 × 8)を使用した、一般的なハッシュアルゴリズムの解読速度は以下の通りです:
| ハッシュアルゴリズム | 速度 (H/s) | 8文字(94文字セット)の解読時間 |
|---|---|---|
| MD5 | ≒ 200 GH/s | ≒ 8時間 |
| SHA-1 | ≒ 70 GH/s | ≒ 24時間 |
| bcrypt (コスト10) | ≒ 184 kH/s | ≒ 1,100年 |
| Argon2id | ≒ 1 kH/s | ≒ 200,000年 |
この表は、サーバー側での 適切なパスワードハッシュ化 がいかに重要であるかを示していますが、16文字のランダムなパスワードがいかにMD5ハッシュに対しても耐性があるかも示しています。
レインボーテーブル
ストレージと引き換えに速度を得る、計算済みのハッシュ対パスワードのテーブル。ハッシュ化の前に各パスワードに一意のランダムな値を追加する ソルト (Salting) によって、完全に無効化されます。bcryptやArgon2のような現代的なアルゴリズムは、設計段階でソルトを含んでいます。
クレデンシャル・スタッフィング
あるサイトの漏洩から得たユーザー名とパスワードのペアを使用して、他のサービスを攻撃すること。防御策は サイトごとに固有のパスワードを使用すること であり、これこそがパスワードマネージャーの独壇場です。
なぜブラウザベースのパスワード生成がより安全なのか
当ツールは、JavaScriptを使用してブラウザ内で完全にパスワードを生成します。データがデバイスから送信されることはありません。これが重要な理由は以下の通りです:
- サーバーへの送信がない —— パスワードがネットワークパケットに触れることがありません。
- サーバーログに残らない —— 召喚、漏洩、侵害される対象が存在しません。
- 生成時にサードパーティへの依存がない —— 生成中にAPI呼び出しや外部スクリプトの実行がありません。
- 再現・検証可能 —— ソースコードを検査してロジックを確認できます。
これをサーバー側の生成器と比較してみてください。HTTPSを使用していても、生成されたパスワードはサーバーのメモリに存在し、アクセスログに記録される可能性があり、運営者の信頼性に完全に依存することになります。
関連するWeb APIは非常にシンプルです:
// ブラウザのCSPRNG —— すべての現代的なブラウザで利用可能
const buffer = new Uint8Array(32);
self.crypto.getRandomValues(buffer);
// bufferには32バイトの暗号学的にランダムなバイトが含まれる
パスワードの保存:bcrypt、scrypt、Argon2
サービスがパスワードを保存する際、決して平文や可逆的な暗号形式で保存してはいけません。正しいアプローチは、パスワードハッシュ関数 (PHF) を使用することです。これは、この目的のために特別に設計された低速な一方通行の関数です。
bcrypt
1999年にNiels ProvosとDavid Mazièresによって設計されました。ハードウェアの高速化に合わせて調整可能な コスト係数 (Cost Factor) が組み込まれています。コスト12は、Blowfishキーセットアップの 2¹² = 4,096 回の反復を意味します。今日でも標準的で広くサポートされています。
scrypt
2009年にColin Percivalによって設計されました。メモリハード (Memory-hard) な設計で、CPU時間だけでなく大量のRAMを必要とするため、GPUやASICによる攻撃コストを増大させます。パラメータ:N (CPU/メモリコスト)、r (ブロックサイズ)、p (並列化係数)。
Argon2
2015年のPassword Hashing Competition (PHC) の優勝者 です。3つのバリエーションがあります:
- Argon2d: GPU耐性があるが、サイドチャネル攻撃に脆弱
- Argon2i: サイドチャネル攻撃耐性があるが、GPU耐性は低い
- Argon2id: ハイブリッド —— 推奨されるデフォルト
Argon2idで m=65536 (64MBメモリ)、t=3 (3反復)、p=4 (4スレッド) が、現在新しいアプリケーションにおけるゴールドスタンダードです。
二要素認証:不可欠な補完策
完璧なパスワードであっても、フィッシング、キーロガー、データ漏洩によって盗まれる可能性があります。二要素認証 (2FA) は、盗まれたパスワードだけでは不十分であることを保証します。
2FAメソッド(弱いものから強いものへ)
| メソッド | メカニズム | 攻撃耐性 |
|---|---|---|
| SMS OTP | テキストメッセージで送信されるコード | フィッシング、SIMスワップに脆弱 |
| TOTP (Google Authenticator) | 時間ベースの6桁コード (RFC 6238) | リアルタイムフィッシングに脆弱 |
| プッシュ通知 | スマホで承認/拒否 | フィッシング(MFA疲労攻撃)に脆弱 |
| ハードウェアキー (FIDO2/WebAuthn) | YubiKey, Passkey | フィッシング耐性あり |
| パスキー (Passkeys) | デバイスに紐づいた暗号鍵 | 最強。パスワードを置き換えるもの |
FIDO2/WebAuthnハードウェアキーやパスキーは、暗号学的なチャレンジ・レスポンスが特定のドメインに紐づいているため、設計上フィッシング耐性があります。偽サイトが資格情報を再利用することはできません。
ベストプラクティス・サマリー
- パスワードマネージャーを使用する —— すべてのアカウントに対して固有のパスワードを生成・保存する。
- 重要なアカウントは最低16文字、その他は最低12文字とする。
- 2FAを有効にする —— 可能であればFIDO2/WebAuthnまたはTOTPを使用し、SMSは避ける。
- パスワードを使い回さない —— 1つのサイトの漏洩が他のサイトに波及しないようにする。
- HaveIBeenPwnedを確認する —— 自分のメールアドレスやパスワードが既知の漏洩に含まれていないかチェックする。
- マスターパスワードにはパスフレーズを使用する —— Dicewareで6語以上。覚えやすく、極めて強力。
- 「複雑さの劇場」に騙されない ——
P@ssw0rd123はxK8mLq2vZnRjよりもはるかに脆弱である。 - 長さを優先する —— 20文字のランダムな小文字(94ビット)は、12文字の複雑な文字列(78ビット)に勝る。
- 漏洩したパスワードを即座に更新する —— 侵害されたときだけ変更し、恣意的なスケジュールでは変更しない。
- 漏洩監視ツールを使用する —— Firefox Monitorや1Password Watchtowerなどのサービスで、アカウントを継続的に監視する。
よくある質問
Q: パスワードの長さはどのくらいにすべきですか? ほとんどのアカウントでは、フル94文字セットからランダムに選んだ16文字(約105ビットのエントロピー)で十分です。高価値なアカウント(銀行、メール、パスワードマネージャー)には、20文字以上または6語のパスフレーズを使用してください。
Q: オンラインのパスワード生成器を使っても安全ですか? すべての生成プロセスがクライアント側(ブラウザ内)で行われ、サーバーとの通信がない場合に限ります。当ツールはこの要件を満たしています。ブラウザのネットワークタブを確認して、パスワード生成時にリクエストが発生していないことを確かめてください。
Q: 記号を含めるべきですか? 記号は1文字あたりのエントロピーを増加させる(小文字のみの5.17ビットに対し、6.55ビット)ため、サイトが許可している場合は含めるべきです。ただし、記号のない長いパスワードは、記号のある短いパスワードと同等のエントロピーを持つことができます。
Q: 量子コンピュータはパスワードを解読できますか? グローバーのアルゴリズムにより、量子コンピュータは総当たり攻撃を二次的に高速化し、実質的にセキュリティビットを半減させます。256ビットの鍵は128ビット相当になります。パスワードの場合、長期的な量子耐性を得るには256ビットのエントロピー(94文字セットなら40文字相当)が必要になります。現在のほとんどの脅威に対しては、128ビットのエントロピー(20文字のランダムな文字)で十分すぎるほどです。
Q: ILovePizza2024 のような覚えやすいパスワードの何がいけないのですか?
これらは辞書攻撃に弱いです。Hashcatのルールエンジンは、一般的なフレーズの何百万ものバリエーション(リートスピーク、大文字化、数字の追加など)を簡単に生成できます。一見個人的なパスワードであっても、攻撃者が統計的にモデル化できるパターンに従っています。
Q: このツールはどのようにランダム性を生成していますか?
オペレーティングシステムのCSPRNGに裏打ちされたWeb Cryptography APIの crypto.getRandomValues() を使用しています。これは、TLS/SSL、SSHキー生成、およびブラウザ内の他の暗号化操作で使用されるものと同じ乱数生成源です。