パスワードセキュリティ完全ガイド:真に信頼できる強力パスワードの生成と管理方法
あなたのパスワード、思っているよりずっと脆弱かもしれない
ほぼ毎月のように、大手サイトのユーザーデータ漏洩のニュースが流れる。漏洩後に最も危険なのは「パスワードを見られた」ことではなく、大多数の人が同じパスワードを使い回していることだ——Aサイトで漏れたIDとパスワードを攻撃者がBサイトやCサイトで試せば、十中八九そのままログインできてしまう。
また別の極端な例として、P@ssw0rd1! を「十分複雑」と信じ込んでいる人もいる。これは自己欺瞞に過ぎない。私たちがツールライブラリのパスワードツールを開発してきたいわゆる「強さ」は自分で「複雑だと思う」かどうかではなく、実際に計算される難易度で決まる。
Have I Been Pwnedなどの漏洩データベースによると、リスト攻撃に使われる弱いパスワードはせいぜい数百のバリエーションしかない。password、123456、qwerty、P@ssw0rd——これらが実際の漏洩データに占める割合は驚くほど高い。あなたが「工夫した」つもりのパスワードも、攻撃者の目にはすでに公開されたシナリオに過ぎない。
攻撃者はどうやってパスワードを破るのか
- クレデンシャルスタッフィング(Credential Stuffing):他から購入/漏洩したIDとパスワードを自動的に大量のサイトで試す。これが「パスワード使い回し」の最も致命的な理由——1つのアカウントが漏れれば、すべてのアカウントが裸同然になる。
- ブルートフォース/辞書攻撃:短いパスワードや一般的な単語の組み合わせは、一般向けGPUで数秒から数分で総当たりできる。コンシューマー向けGPU1枚で毎秒数十億回のハッシュ計算が可能だ。
- ソーシャルエンジニアリングと個人情報:誕生日、名前、ペット名、ナンバープレート。攻撃者はあなた(またはあなたのSNSアカウント)を少し調べれば、これらを辞書に優先的に追加して試す。
- レインボーテーブル(Rainbow Table):あらかじめ「よくあるパスワード → ハッシュ」の対応表を計算しておき、漏洩したハッシュデータベースを逆引きする。ソルト(salt)を使えばこれを無効化できる。
これらに共通する前提は:パスワードが一般的すぎるか、短すぎるか、あなたの情報に関連しているかだ。この3点を避ければ、解読コストが高くなりすぎて誰も相手にしなくなる。
本当の「強さ」とは何か
3つの基準を、重要な順に:
- 十分な長さ:12–16文字以上。長さが解読コストに与える影響は指数関数的で、どんな「記号を1つ追加する」より効果的だ。12桁のランダムパスワードは、8桁の複雑パスワードより数桁も解読が難しい。
- 真のランダム性:文字は暗号学的乱数生成器から得られたもの。人間が脳内で考えたものではない。人間が作るパスワードには明確なパターン(先頭大文字、末尾数字、一般的な単語など)があり、エントロピーが低い。
- ユニークであること:サイトごとに異なるパスワードを使う。これだけでクレデンシャルスタッフィングを防げる。
パスワード別の解読所要時間の目安(オフラインブルートフォースベース、攻撃者の計算能力による):
| パスワード | おおよその解読コスト |
|---|---|
password123 |
一瞬 |
P@ssw0rd1! |
辞書攻撃で数秒 |
| 8桁ランダム英数字 | 数時間〜数日 |
| 12桁ランダム英数字記号 | 数千年以上 |
| ランダム4単語のパスフレーズ | こちらも数千年 |
エントロピー:「強さ」を定量化する
暗号学では「エントロピー(entropy、単位bit)」でランダム性を測る。大まかな式:エントロピー ≈ 文字集合サイズの対数 × 長さ。
- 小文字のみ(26種):各文字あたり約 log₂26 ≈ 4.7 bit
- 数字追加(36種):約 5.17 bit
- 大文字小文字+数字+記号(約95種):約 6.57 bit
したがって:
| パスワード | 推定エントロピー |
|---|---|
| 8桁複雑文字 | 約52 bit |
| 12桁複雑文字 | 約79 bit |
| ランダム4単語(各単語約11bit) | 約44–55 bit |
| ランダム5単語 | 約55–65 bit |
経験則:エントロピー ≥ 60 bit で「強い」、≥ 80 bit で「非常に強い」。だからパスフレーズは単語数が十分かつ真にランダムであれば、ランダム文字列と同じだけの耐性を発揮する。
生成はツールに任せる、頭で考えない
自分でパスワードを考えても、どんなに「ランダム」に見えても習慣がにじみ出る。ツールに暗号学的乱数で生成させるのが信頼できる:
- ランダムパスワード/トークン生成:長さと文字集合(大文字小文字、数字、記号)を設定可能。内部で
cryptoの乱数を使用。 - 生成後はパスワード強度分析でチェックし、よくあるルールで誤って「弱い」と判定されていないか確認する。
長さは16文字以上を推奨。1文字増やすごとに解読コストは数十倍になる。以下が正しい生成方法と間違った生成方法の比較:
// ❌ 間違い:Math.randomは疑似乱数で予測可能、パスワードに使ってはいけない
const weak = Math.random().toString(36).slice(2, 10);
// ✅ 正しい:Web Cryptoの暗号学的乱数を使用
function genPassword(len = 16) {
const chars = 'ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz23456789';
const arr = new Uint32Array(len);
crypto.getRandomValues(arr);
return Array.from(arr, n => chars[n % chars.length]).join('');
}
パスフレーズ:覚えやすく、かつ強い
ランダム文字列が覚えにくいなら、パスフレーズ(Passphrase) を試してほしい——Diceware方式:互いに関連のない4–5個のランダム単語を選び、区切り文字でつなぐ。例:correct-horse-battery-staple(有名な例)。
同じ長さのランダム文字列より覚えやすく、エントロピーは決して低くない:各単語が約10–13bitのエントロピーを持ち、5単語で50–65bit。これはほとんどのランダム短パスワードを上回る。手書きで覚えるタイプのユーザーには最も実用的な方法だ。
名言、歌詞、「文の頭文字をつなげる」方式は使わないこと——それらは依然として予測可能なパターンだ。単語は真にランダムに選ばなければならない(ツールのランダム単語機能を使い、自分で選ばない)。
発展:単語の間にランダムな数字や記号を挟む(例:correct-7-horse-battery-3-staple)。エントロピーはさらに上がり、それでも覚えやすい。
管理:マネージャー+ユニーク+二要素認証
強力なパスワードを生成するのは第一歩に過ぎない。覚えられなければ意味がない。
- パスワードマネージャーを使う(Bitwarden、1Password、KeePass など):サイトごとにユニークな強パスワードを保存し、あなたはマスターパスワード1つだけを守ればよい。マスターパスワードには上記のパスフレーズ方式を推奨。良いマネージャーはゼロナレッジアーキテクチャ——あなたのデータはローカルで暗号化され、サービス事業者も平文を見ることはできない。
- 二要素認証(2FA)を有効にする:パスワードが漏れても、もう一段の動的コードがなければログインできない。TOTPツールでワンタイムコードを生成できる。SMSより信頼性が高い。
- 重要なアカウントはSMS認証だけに頼らない:SIMスワップ攻撃でSMSを乗っ取られる可能性がある。TOTPやハードウェアキー(パスキー/Passkeyなど)を優先しよう。
二要素認証の方式別セキュリティ順位:
| 方式 | セキュリティ | 備考 |
|---|---|---|
| ハードウェアキー/パスキー(WebAuthn) | 最高 | フィッシング耐性あり、盗む秘密なし |
| TOTP認証アプリ | 高い | SMS非依存、推奨 |
| SMSショートメッセージ | 低い | SIMスワップで乗っ取り可能 |
| メール認証コード | 中〜低 | メールが漏れると連鎖的に無効に |
開発者視点:秘密の保存方法
バックエンドを書いているなら、鉄則は1つ:パスワードを平文で保存してはいけない。
ハッシュ化であって、暗号化ではない
パスワードはハッシュとしてのみ保存する——bcrypt/Argon2/PBKDF2 を使用し、ソルトも必ず加える。注意:「ハッシュ」と「暗号化」は異なる:暗号化は可逆だが、ハッシュは不可逆だ。あなたはユーザーのパスワードを復元する必要はなく、すべきでもない。
ツールライブラリにはハッシュツール(MD5/SHAなどのダイジェスト)とbcryptツール(パスワードハッシュ専用)がある。重要:MD5/SHAは汎用ダイジェストアルゴリズムで計算が速すぎるため、パスワード保存には適さない——ブルートフォース攻撃に対抗できない。正式な保存にはbcrypt/Argon2/scryptのような「スローハッシュ」を使うこと。
// Node.js:bcryptでパスワード保存(正しい方法)
import bcrypt from 'bcrypt';
const saltRounds = 12; // 大きいほど遅く安全、12が一般的
const hash = await bcrypt.hash(password, saltRounds);
// hash をデータベースに保存、passwordは保存しない
// ログイン時に検証
const ok = await bcrypt.compare(inputPassword, hashFromDb);
// Node.js:Argon2(より現代的、新規プロジェクトに推奨)
import argon2 from 'argon2';
const hash = await argon2.hash(password, {
type: argon2.argon2id,
memoryCost: 65536, // 64 MB
timeCost: 3,
parallelism: 1,
});
ソルト、ペッパー、ブルートフォース対策
- ソルト:ユーザーごとにランダムな文字列を生成し、ハッシュに混ぜてデータベースに保存。同じパスワードでも異なるハッシュを生成するため、レインボーテーブルとリスト攻撃を無効化する。bcrypt/Argon2は自動でソルトを付与するので、そのまま使えばよい。
- ペッパー:グローバルな秘密鍵で、データベースには保存しない(環境変数/キー管理サービスに保管)。パスワードをハッシュする前にペッパーを結合する。データベースが漏洩しても、ペッパーがなければパスワードの解読は困難。
- レート制限とロックアウト:ログインAPIは必ずレート制限、失敗回数ロックアウト、キャプチャを実装してオンラインブルートフォースを防ぐ。
- タイミング攻撃:「定数時間比較」でハッシュを検証する(bcrypt.compareは内部で既に実装済み)。
==での直接比較は避ける。
可逆性が必要な場合のみ暗号化を使う
例えば、復元が必要な共有鍵、ユーザー認証済みのサードパーティトークンなどにはAES-256-GCMツールを使用。パスワードをPBKDF2で鍵に派生し、すべてローカルで処理する。ただし「ユーザーログインパスワード」は決して可逆にしてはいけない——それは設計ミスだ。
ユーザーパスワードをログに書き出さない、平文でデータベースに保存しない、フロントエンドで「パスワード強度」以外の処理をしない。フロントエンドの強度表示はあくまでUXであり、本当のセキュリティはバックエンドのハッシュにある。
コンプライアンス参考:NISTの新しい考え方
米国NIST 800-63Bは、「30日ごとのパスワード変更義務」「大文字小文字+数字+記号の必須組み合わせ」といった従来のルールをすでに否定している。新しい推奨:
- 長さ優先(最低8、できればそれ以上)、複雑な組み合わせの強制はしない。
- 定期的な変更を強制しない(漏洩していなければ変更不要。強制変更はむしろ弱いパスワードを生む)。
- パスワードが既知の漏洩データベースに含まれているかチェックする(k-anonymityインターフェースでプレフィックスだけ照合、完全なパスワードは送信しない)。
- 貼り付けを許可する(パスワードマネージャーを使いやすくするため)。
- 最大長のみ制限し、特殊文字の制限はしない。
パスワード強度分析ツールの実装はこれらの原則を参考にしている——「記号があるか」だけでなく、長さと一般的なパターンに該当するかを評価する。
よくあるエラー
| エラー | 結果 | 正しい方法 |
|---|---|---|
| 全サイトで同じパスワード | 1箇所漏洩ですべて崩壊 | サイトごとにユニーク |
P@ssw0rd 風の置換 |
辞書で即解読 | 真ランダム/パスフレーズ |
| スマホのメモ帳に保存 | スマホ紛失で終了 | パスワードマネージャー |
| SMSのみの2FA | SIMスワップで乗っ取り | TOTP/ハードウェアキー |
| 短いPINをパスワードに | ブルートフォースで即解読 | 12–16文字以上 |
| パスワードを平文保存 | 漏洩で全ユーザー流出 | bcrypt/Argon2でハッシュ |
| MD5/SHAでパスワード保存 | 高速ハッシュでブルートフォースに弱い | スローハッシュアルゴリズム |
よくある質問
パスワードは定期的に変更すべき? 漏洩の兆候がなければ不要(NIST新ガイドラインに準拠)。30日ごとの強制変更は、むしろ弱いパスワードを書いたり末尾の数字だけ変える習慣を生む。漏洩が確認されたら変更する。
パスフレーズとランダム文字列、どちらが良い? どちらでも良い。重要なのは長さとランダム性。パスフレーズは覚えやすさで勝り、マスターパスワードや手書き記録に適している。ランダム文字列はマネージャーが自動入力するサイト向け。
あるサイトが漏洩したと知ったら? そのサイト(および同じパスワードを使っている全サイト)のパスワードをすぐに変更 → 2FAを有効にする → Have I Been Pwnedで自分のメールアドレスが漏洩していないか確認する。
パスワードマネージャーのマスターパスワードを忘れたら? マスターパスワードには通常、復旧機能がない(これが安全性の代償だ)。だからマスターパスワードは本当に覚えられて、かつ十分に長いパスフレーズを使い、オフラインバックアップ(手書きして鍵付き引き出しに保管)を残しておくこと。
開発者:どのハッシュアルゴリズムを使うべき? 新規プロジェクトではArgon2idを優先。既存システムとの互換性が必要ならbcrypt(cost≥12)。MD5/SHAシリーズをパスワード保存に直接使わないこと。
アカウントセキュリティセルフチェックリスト
1. 使い回しているパスワードはないか? → /encode/password でユニークな強パスワードを生成して順次置き換え
2. 長さは十分か(≥12、推奨16+)? 足りなければ延長
3. 二要素認証は有効か? → TOTP(/utils/totp)またはPasskeyを優先、SMSのみは避ける
4. 開発者:パスワードはハッシュ保存か? → /encode/bcrypt、平文もMD5/SHAもダメ
5. マスターパスワードは覚えやすく強いか? → パスフレーズ方式で、オフラインバックアップを確保
6. 漏洩データベースに載っていないか? → 定期的にHave I Been Pwnedで確認
この6項目をチェックすれば、あなたのアカウントセキュリティレベルは大多数の人より一段上になる。パスワードは、早く真剣に向き合うほど、後でヒヤヒヤしなくて済む。関連する画像やファイルのプライバシー処理についてはデータプライバシーガイドを参照。
ブラウザローカルツールを無料で試す →