「ランダムな文字列が欲しい」という場面は開発・運用のあらゆる場面で出てきます。パスワード・APIキー・セッションID・CSRFトークン・招待コード——それぞれに適した長さと文字種が異なります。用途を整理した上で、安全な生成方法を選びましょう。
ランダム文字列が必要な主な用途
| 用途 | 推奨文字数 | 推奨文字種 |
|---|---|---|
| パスワード(一般サービス) | 12〜16文字 | 英大小文字+数字+記号 |
| パスワード(金融・重要) | 20文字以上 | 英大小文字+数字+記号 |
| APIキー | 32〜64文字 | 英数字(Base64またはHex) |
| セッションID | 32文字以上 | 英数字 |
| CSRFトークン | 32文字以上 | 英数字 |
| 招待コード・ワンタイムコード | 6〜10文字 | 数字または英数字(大文字) |
| URLトークン(メール認証など) | 32文字以上 | 英数字 |
パスワードとランダム文字列の違い
厳密には「パスワード」も「ランダム文字列」の一種ですが、用途で使い分けが必要です。
パスワードは人間が入力するものなので、記号を含めても文字数は12〜20文字程度に収めるのが実用的です。記号を含めることでエントロピー(推測困難さ)が上がります。
APIキーやトークンはプログラムが扱うので、文字種を英数字に絞って32〜64文字の長さで強度を確保します。記号はURLや設定ファイルでのエスケープ処理が必要になるため避けるのが一般的です。
文字数と安全性の目安
ランダム文字列の強度は「使える文字の種類数 ^ 文字数」の組み合わせ数で決まります。
| 文字種 | 1文字あたりのビット数 | 16文字での組み合わせ |
|---|---|---|
| 数字のみ(10種) | 3.32 bit | 10^16 ≈ 2^53 |
| 英小文字のみ(26種) | 4.7 bit | 26^16 ≈ 2^75 |
| 英大小文字+数字(62種) | 5.95 bit | 62^16 ≈ 2^95 |
| 英大小文字+数字+記号(95種) | 6.57 bit | 95^16 ≈ 2^105 |
現代のコンピュータで総当たり攻撃(ブルートフォース)を現実的に防ぐには 80bit以上 の強度が目安です。英数字16文字なら十分なエントロピーがあります。
安全な生成方法
ブラウザのJavaScriptで生成する
crypto.getRandomValues() は暗号学的に安全な乱数を生成します。Math.random() は予測可能な疑似乱数のため、パスワードやトークンには使ってはいけません。
function generateToken(length = 32) {
const chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
const array = new Uint8Array(length);
crypto.getRandomValues(array);
return Array.from(array, b => chars[b % chars.length]).join('');
}
### PHPで生成する
// PHP 7+ の random_bytes() は暗号学的に安全
$token = bin2hex(random_bytes(32)); // 64文字のHex文字列
### コマンドラインで生成する
# 32文字の英数字(macOS/Linux)
openssl rand -base64 32 | tr -dc 'A-Za-z0-9' | head -c 32
# UUIDを生成
uuidgen
## よくある間違い
Math.random()をパスワード生成に使う: JavaScript のMath.random()は暗号学的に安全ではないため、予測される可能性があります。必ずcrypto.getRandomValues()を使いましょう- 短いAPIキーを使い回す: 8文字のAPIキーは短すぎます。漏洩リスクを考えても32文字以上を推奨します
- 同じ乱数シードを使い回す: 乱数生成器に固定のシードを与えると、同じ出力が繰り返されます
パスワード・ランダム文字列生成ツールでは、用途に合わせて文字種・長さを選んで安全なランダム文字列をブラウザ内で即生成できます。サーバーへの送信は一切ありません。