使い方
- 「長さ」を設定し、「単位」で「ランダムデータのバイト数」と「文字数」(Base64 の文字数)のどちらで数えるかを選びます。鍵を作る場合はバイト数を使います。32 バイトで 256 ビットの鍵になります。
- 「生成数」で必要な件数を設定し、「区切り文字」を「改行」「カンマ」「スペース」から選びます。
- 「種類」で「標準(RFC 4648)」または「URL セーフ(RFC 4648 §5)」を選びます。単位がバイト数の場合は、送り先のシステムが = 記号を想定していなければ「パディング」をオフにすることもできます。
- 「生成」をクリックして新しい値を作成し、「すべてコピー」でコピーするか、「ダウンロード」で一覧を保存します。
バイト数、文字数、エントロピー
ランダムな文字列の強度は、エントロピーのビット数で表します。ランダムなバイトが 1 つ増えるごとに 8 ビット加わるため、16 バイトなら 128 ビット、32 バイトなら 256 ビットになります。Base64 はそのバイト列の書き表し方を変えるだけで、1 文字が 6 ビットを表し、3 バイトが 4 文字になります。ツールは文字列ごとのエントロピーを表示するので、ひと目で確認できます。
「単位」をランダムデータのバイト数にすると、出力をデコードしたときにちょうど指定した数のランダムなバイトになります。鍵やシークレットに必要なのはこちらです。文字数にすると、指定したとおりの文字数の文字列が得られ、各文字は 64 文字のアルファベットから一様に選ばれます。固定長のトークンを求め、それをテキストとして保存するシステムで使ってください。
| バイト数 | Base64 の文字数 | エントロピー | 主な用途 |
|---|---|---|---|
| 12 | 16 | 96 ビット | AES-GCM のナンス(IV) |
| 16 | 24(パディングなしで 22) | 128 ビット | ソルト、セッショントークン、CSRF トークン、AES-128 の鍵 |
| 32 | 44(パディングなしで 43) | 256 ビット | AES-256 や HMAC-SHA256 の鍵、HS256 のシークレット、API キー |
| 64 | 88(パディングなしで 86) | 512 ビット | HMAC-SHA512 の鍵、HS512 のシークレット |
ランダムな Base64 値の主な用途
- JWT のシークレット。RFC 7518 では、HMAC の鍵の長さはハッシュ出力の長さ以上であることが求められます。HS256 では 32 バイト、HS384 では 48 バイト、HS512 では 64 バイトです。シークレットの文字列をそのまま使うライブラリもあれば、先に Base64 デコードするライブラリもあるため、お使いのライブラリがどちらを想定しているか確認してください。JWT デコーダーはどちらの形式のシークレットでも HS256~HS512 の署名を検証でき、HMAC 生成ツールは鍵をテキスト、16進数、Base64 のいずれの形式でも受け付けます。
- アプリケーションの鍵。たとえば Laravel は、32 バイトの暗号鍵を
.envファイルにAPP_KEY=base64:...の形で保存します。これは、このツールで 32 バイトを指定して生成した文字列と同じ形式です。 - Kubernetes の Secret。
dataの下に置く値は、パディング付きの標準 Base64 でなければなりません。単位をバイト数、種類を標準にし、パディングをオンにして生成した文字列はそのまま記述でき、Pod には元のランダムなバイト列が渡されます。アプリケーションが Base64 のテキストそのものを必要とする場合は、代わりにstringDataの下に置いてください。 - URL に含めるトークン。パスワードリセット用のリンクや招待コードなど、URL に含めて受け渡すトークンには URL セーフの種類を使用してください。
+と/が-と_に置き換わります。詳しくは Base64URL のページをご覧ください。
Math.random でなく crypto.getRandomValues を使う理由
Math.random() は高速な汎用の乱数生成器です。その出力は予測できないようには設計されておらず、エンジンによっては少数の値から内部状態を復元できてしまいます。このツールが使う crypto.getRandomValues() は、オペレーティングシステムがシードを供給する暗号論的に安全な乱数生成器で、openssl rand や Python の secrets モジュールと同じ種類の乱数源です。値はお使いのデバイス上で生成され、送信も保存もされません。
コードでランダムな Base64 を生成する
# シェル:32 バイトの乱数を Base64 で出力(44 文字)
openssl rand -base64 32
head -c 32 /dev/urandom | base64
# Python
import base64, secrets
base64.b64encode(secrets.token_bytes(32)).decode()
secrets.token_urlsafe(32) # URL セーフ、パディングなし、43 文字
// Node.js
const crypto = require('crypto');
crypto.randomBytes(32).toString('base64');
crypto.randomBytes(32).toString('base64url'); // URL セーフ、パディングなし
// ブラウザ
const bytes = crypto.getRandomValues(new Uint8Array(32));
btoa(String.fromCharCode(...bytes));
よくある質問
ランダムな鍵やシークレットはどのくらいの長さにすべきですか?
セッション ID、CSRF トークン、ソルトのように、一意で推測できなければよい値であれば 16 バイト(128 ビット)で十分です。AES-256 の鍵、HMAC-SHA256 の鍵、HS256 のシークレットには 32 バイト(256 ビット)を、HMAC-SHA512 と HS512 には 64 バイトを使用してください。
openssl rand -base64 32 と同じものですか?
= が 1 つ付き、デコードすると 32 バイトのランダムなバイト列になります。もちろん、値そのものは毎回異なります。単位はバイト数と文字数のどちらを使えばよいですか?
暗号鍵や Kubernetes の Secret のように、文字列がデコードされて使われる場合はバイト数を使います。システムが決まった長さのトークンを必要とし、テキストのまま使う場合は文字数を使います。文字数を単位にして生成した文字列は、長さが 4 の倍数のときにしか、問題なくデコードできることが保証されません。
URL セーフの種類が必要になるのはどんなときですか?
/ が URL のパスを区切ってしまい、+ はフォーム形式でエンコードされたクエリ文字列ではスペースに変わります。URL セーフの Base64 では代わりに - と _ を使い、通常はパディングを付けずに記述します。生成した値はどこかに保存または送信されますか?
いいえ。値はブラウザ内の JavaScript で生成され、送信されることはなく、ページを離れると消えます。実際のシークレットとして使う値は、チャットのメッセージやチケットに書かず、パスワードマネージャーやシークレット管理サービスに保管してください。