一言で言うと
パスワードジェネレーターは、毎秒何十億回試行してもコンピューターが推測するのが事実上不可能なほどランダムな文字列を生成します。
解決する問題
人間は歩き、話し、そしてパターンを作り出す機械です。私たちはショートカットを見つけたり、雲の中に顔を見出したり、メロディーを覚えたりするのは得意です。しかし、ランダムなものを作り出すのは、からっきしダメなのです。
パスワードの作成を求められると、私たちの脳は知っているものに頼ってしまいます。ペットの名前 (fluffy1)、重要な日付 (MomBday1965!)、好きなスポーツチーム (GoPackGo2024)、あるいはキーボードのパターン (qwerty12345) などです。o を 0 に変えたり、最後に感嘆符を付けたりして、賢くやっているつもりかもしれませんが、それは少し複雑なだけで、依然として予測可能なパターンに従っているに過ぎません。
コンピューティングの初期の頃はそれでも問題ありませんでした。しかし、処理能力が爆発的に向上するにつれて、攻撃者は推測ゲームを自動化しました。彼らは辞書にあるすべての単語を試すツール(「辞書攻撃」)を構築しました。その後、数字、よくある置き換え、特殊文字などを追加しました。今日、最新のGPUは毎秒何十億回もの推測ができます。P@ssw0rd1! のようなパスワードは人間には複雑に見えるかもしれませんが、コンピューターにとっては、数分、いや数秒で推測できてしまう、たやすく攻略できる標的です。
パスワードジェネレーターが解決するのは、この「人間の脳」問題です。それは、偏見も、好きなペットの名前も、「ランダムに見える」という概念も持たないマシンに、秘密鍵の作成という仕事をアウトソーシングします。マシンはただ数学的な原則に従って、事実上、純粋なノイズである文字列を生成します。そしてそのノイズは、セキュリティ意識の高い開発者にとっては、美しいシンフォニーなのです。
舞台裏の仕組み
優れたパスワードジェネレーターは、ただキーをめちゃくちゃに叩いているわけではありません。それは、エントロピーという数学的な概念に根ざした、注意深く計算されたプロセスです。ハイテクなサイコロ振りマシンと考えてください。
秘密の材料:エントロピー
クリプトグラフィにおいて、エントロピーは予測不能性、つまりランダム性の尺度です。エントロピーが高いということは、値を推測するのが非常に難しいことを意味し、低いということは予測可能であることを意味します。あなたの誕生日はエントロピーが低いです。100回コインを投げた結果はエントロピーが高いです。
パスワードジェネレーターは、その仕事を遂行するために高品質なランダム性の源を必要とします。最新のウェブブラウザでは、このソースは通常、Web Crypto API、具体的には crypto.getRandomValues() のような関数です。これは、昔ながらの Math.random() とはワケが違います。単純で予測可能なアルゴリズムを使う代わりに、オペレーティングシステムの持つエントロピー・プールを利用します。このプールはカオスの大釜であり、以下のような予測不可能な入力でかき混ぜられています。
- あなたのマウスの動きやクリックの正確なタイミング
- あなたのキーボードストロークのリズム
- ハードウェアデバイス(ファンやハードドライブなど)からのノイズ
- ネットワークパケットのタイミング
ブラウザは、この暗号論的に安全な疑似乱数生成器(CSPRNG)を使用して、セキュリティ目的で十分に予測不可能な数値のストリームを取得します。これが私たちのパスワードの原材料です。
文字プールの構築
次に、ジェネレーターは選択可能な「アルファベット」を定義します。これは単なるA〜Zではありません。あなたが許可した文字の完全なセットです。典型的な構成は次のようになります。
- 小文字:
abcdefghijklmnopqrstuvwxyz(26文字) - 大文字:
ABCDEFGHIJKLMNOPQRSTUVWXYZ(26文字) - 数字:
0123456789(10文字) - 記号:
!"#$%&'()*+,-./:;<=>?@[\]^_`{|}~(32文字)
4つすべてのセットを有効にすると、文字プール(N)のサイズは 26 + 26 + 10 + 32 = 94 の可能な文字になります。このプールのサイズは、最終的なパスワードの強度における重要な要素です。
サイコロを振る:アルゴリズム
ランダムな数のソースと文字のプールがあれば、プロセスは驚くほどシンプルです。
- ランダムな数を取得する: CSPRNGに0から93(文字プールの合計サイズマイナス1)までのランダムな数を要求します。
- 文字を選ぶ: その数をインデックスとして使用し、プールから文字を選びます。たとえば、ランダムな数が
74で、プール内の74番目の文字が&であれば、&がパスワードの最初の文字になります。 - 繰り返す: これを、希望するパスワードの長さ(
L)だけ何度も繰り返します。
簡略化されたJavaScript風の例は次のようになります。
function generatePassword(length, characterPool) {
let password = "";
const poolSize = characterPool.length;
// 効率化のため、ランダムな数値の配列を一度に取得する
const randomValues = new Uint32Array(length);
window.crypto.getRandomValues(randomValues);
for (let i = 0; i < length; i++) {
// ランダムな数を使ってプールから文字を選ぶ
const randomIndex = randomValues[i] % poolSize;
password += characterPool[randomIndex];
}
return password;
}
const allChars = "abc...XYZ...123...#$!..."; // 94文字のプール
const myStrongPassword = generatePassword(16, allChars);
// 結果: "9k&vB$@p!Z*rE#wJ" のようなもの
重要なのは、一様分布を確保することです。つまり、プール内のすべての文字が、パスワードのすべての位置で選択される確率が等しくなければなりません。
強度の測定:ビット単位のエントロピー
では、結果はどれくらい強力なのでしょうか? それを「ビット単位のエントロピー」で測定します。計算式は log₂(組み合わせ総数) です。組み合わせの総数は、文字プールのサイズ(N)をパスワードの長さ(L)で累乗したもの、つまり N^L です。
ビット単位のエントロピーの計算式は次のとおりです: H = L * log₂(N)
これがどのように機能するか見てみましょう。
| 長さ (L) | 文字セット (N) | 組み合わせ総数 (N^L) | エントロピー(ビット数) (H) | 解読時間(毎秒10¹²回の試行) |
|---|---|---|---|---|
| 8 | 小文字のみ (26) | 2080億 | ~37.6 | ミリ秒 |
| 8 | すべての文字 (94) | 6000兆 | ~52.4 | 数分 |
| 12 | すべての文字 (94) | 4.7 x 10²³ | ~78.7 | 数千年 |
| 16 | すべての文字 (94) | 3.7 x 10³¹ | ~104.9 | 数兆年 |
| 24 | すべての文字 (94) | 2.3 x 10⁴⁷ | ~157.3 | 事実上、永遠 |
ご覧のとおり、長さに1文字追加するごとに、強度が単に加算されるのではなく、乗算されます。この指数関数的な成長こそ、16文字のパスワードが8文字のパスワードの単なる2倍の強度ではなく、何千兆の何千兆倍も強力である理由です。これがパスワードセキュリティの数学的な根幹です。
実社会での事例
「Password123」が引き起こした大惨事
あるジュニア開発者、仮にアレックスとしましょう、は新しいプロジェクトのために十数のサービスをやりくりしていました。GitHub、クラウドサーバープロバイダー、データベースサービス、そしていくつかのSaaS監視ツールです。シンプルにするために、彼女は覚えられるパスワード ProjectName2023! を使いました。十分に安全だと感じていました。ある日、バグを追跡するために登録した無名のフォーラムソフトウェア・アズ・ア・サービスがデータ侵害を発表しました。ハッシュ化されたパスワードを含むユーザーデータベースが漏洩したのです。残念なことに、彼らは脆弱なハッシュアルゴリズムを使用しており、数時間のうちにクラッカーはハッシュを平文に戻してしまいました。攻撃者はその後、自動化されたスクリプトを実行し、漏洩した メールアドレス:パスワード の組み合わせを主要なサービスで試しました。そして、アレックスのアカウントで大当たりを引きました。彼女の ProjectName2023! というパスワードによって、彼らは彼女のクラウドプロバイダーとGitHubリポジトリにアクセスできました。彼らはソースコードと顧客データをコピーし、サーバーを消去しました。
教訓: パスワードの使い回しは時を刻む時限爆弾です。どこか一箇所での侵害が、すべての場所での侵害につながります。すべてのサービスには、ユニークでランダムに生成されたパスワードが必要です。
ブルートフォースを跳ね返した話
システム管理者のベンは、新しい公開SSHサーバーのセキュリティを強化していました。このサーバーは魅力的な標的であり、公開された瞬間にボットによってスキャンされることを彼は知っていました。rootユーザーアカウント(いずれにせよ外部からのログインは無効にする予定でした)には、彼はパスワードを考えようとさえしませんでした。彼はすべての文字セットを使用して32文字の完全な意味不明な文字列を生成しました。q#8v...G@z7 のようなものです。一週間後、好奇心からサーバーの認証ログを調べました。彼は恐ろしい光景を目にしました。世界中のIPアドレスから何百万もの失敗したログイン試行があったのです。ボットは執拗なブルートフォース攻撃を実行し、一般的なパスワード、辞書の単語、連続した文字を試していました。しかし、彼の32文字の要塞に対しては、それは山に小石を投げるようなものでした。彼らはかすりもしなかったのです。
教訓: 自動化された無差別な攻撃に対する最初の防衛線は、ブルートフォース攻撃が数学的に実行不可能なほど複雑で長いパスワードです。
ペンテスターの「楽勝」
ペネトレーションテスターのマリアは、ある中規模企業のセキュリティを評価するために雇われました。彼女は「ソーシャルエンジニアリング」と偵察から始めました。ガイド付きのオフィスツアーで歩き回りながら、彼女は人々の仕事スペースをこっそり観察しました。あるモニターの隅に、Winter2024$ と書かれた付箋が貼られていました。それは経理の誰かのもののようでした。このパスワードは古典的な「人間」のパターンに従っていました。一般的な単語、現在の季節/年、そして最後に記号です。これは、覚えやすくありながらポリシー(大文字、数字、記号をそれぞれ1つ以上含むこと)を満たすように設計されたパスワードでした。マリアにとって、それは開いたドアでした。彼女はそれを使って会社の財務ソフトウェアにログインし、機密データにアクセスして操作できた可能性があることを証明しました。
教訓: パスワードポリシーに従っているときでさえ、人間は予測可能なパスワードを作成します。ジェネレーターからの真のランダム性は、しばしば最も弱い環である人間的要素を取り除きます。
よくある間違いと落とし穴
- 怪しいジェネレーターを信用する。 パスワード生成を提供すると謳うランダムなウェブサイトには注意してください。悪意のあるサイトは、作成したすべてのパスワードを記録している可能性があります。信頼できるオープンソースのツールや、ブラウザ内で完全に実行され、コードが外部にデータを送信できないものに固執しましょう。
- 覚えやすさのためにランダム性を犠牲にする。 パスワードを生成した後、覚えやすくするために「微調整」すると、全体の意味がなくなります。攻撃者が悪用する予測可能な人間のパターンを再び注入しただけです。
- 文字セットを無視する。 数字だけで作られた20文字のパスワード(
27182818284590452353)は、文字、数字、記号を使った12文字のパスワードよりもはるかに弱いです。文字プール(N)のサイズは、強度を強力に増幅させる要素です。 - 生成したパスワードを安全でない方法で保管する。
4tG!p$z#qR@...を生成するのは第一段階です。第二段階はそれを安全に保管することです。付箋に書いたり、デスクトップのpasswords.txtに保存したり、自分宛にメールで送ったりしては意味がありません。信頼できるパスワードマネージャーを使用してください。 - たった一つの「破れない」パスワードを使い回す。 素晴らしい25文字のパスワードを生成したとします。あなたはそれを誇りに思い、メール、銀行、ソーシャルメディアに使います。それらのサービスのいずれか一つでも侵害された瞬間、あなたの「破れない」鍵は攻撃者の手に渡り、すべてのアカウントが脆弱になります。
なぜ注目すべきか
もしあなたがコードを書くなら、あなたはシークレットを管理しています。以上です。それがデータベースの接続文字列であれ、サードパーティサービスのAPIキーであれ、サーバーのログイン情報であれ、あるいはあなたが構築しているアプリのデフォルトの管理者アカウントであれ、あなたは常にデジタルキーを作成し、扱っています。
開発者は、別のマシンが推測しようとする可能性のあるシークレットを作成する必要があるときはいつでも、パスワードジェネレーターに手を伸ばすべきです。人間の脳は、ロジック、創造性、問題解決のためのものです。暗号学的に安全なランダム文字列を生成するためのものではありません。パスワードジェネレーターを正しく理解して使用することで、人間の主要な弱点を数学的な確実性に置き換えることができます。これは、あなたが採用できる最もシンプルで効果的なセキュリティプラクティスの一つです。それは自分のアカウントを守るだけでなく、ユーザーのために安全なシステムをゼロから構築することでもあるのです。
さらに深く知る
- NIST Special Publication 800-63B: 米国国立標準技術研究所(NIST)による、デジタルアイデンティティに関する公式ガイドライン。パスワードポリシーや強度に関する現代的な見解が含まれています。
- MDN Web Docs: The Web Crypto API:
crypto.getRandomValues()を含む、暗号操作のためのブラウザ内蔵APIについての詳細な解説。 - OWASP Password Storage Cheat Sheet: Open Web Application Security Project(OWASP)による、サーバー側でパスワードを適切に処理する方法(生成した後)に関する必須のリソース。
- Wikipedia: Password strength: エントロピー計算やブルートフォース攻撃分析など、概念に関する包括的な概要。
- Cloudflare: How we built a password generator: 安全で高品質なパスワードジェネレーターを構築する際に考慮すべき点についての、優れた実世界の解説記事。