桁数と文字種を指定して、ランダムなパスワードをまとめて生成するアプリです。生成はブラウザの中だけで行い、結果はどこにも送信されません。
使い方
- スライダーか数値入力で桁数を決めます(4〜128桁)。
- 使う文字種(英大文字/英小文字/数字/記号)にチェックを入れます。
- 必要に応じて「紛らわしい文字を除く」「各文字種を最低1文字含める」を切り替えます。
- 生成する本数(1〜20本)を選びます。
- 行をクリック(スマホはタップ)するとその1本を、「全部コピー」で表示中の全部をクリップボードにコピーします。
設定を変えた時点で結果は作り直されます。「生成する」ボタンは、同じ条件で引き直したいときに使います。強度は「約103bit(16桁 / 88文字種から)」のように、総当たりに必要なビット数の概算で表示されます。
何に使えるか
ネットワーク機器の初期パスワード、SNMPv3の認証・暗号パスフレーズ、RADIUSやTACACS+の共有シークレット、秘密鍵のパスフレーズなど、人が覚える必要のない文字列を作る場面を想定しています。まとめて発行するときは本数を20本にして、必要な分だけ使ってください。
「紛らわしい文字を除く」は 0 O o 1 l I を候補から外します。パスワードを紙で渡す、電話で読み上げる、コンソールから手で打ち込む、といった経路がある場合に使います。逆にコピー&ペーストで完結するなら、外さないほうが文字種が増えて強度は上がります。
記号は機器側で使える文字が限られていることがあります。特にコンフィグに直接書く場合、機器のパーサによっては特定の記号でパスワードが途中までしか読まれないことがあります。記号を含めたパスワードを設定したあとは、実際にそのパスワードでログインし直せるところまで確認してください。
強度の目安は、40bit未満が「弱い」、80bit以上で「強い」としています。総当たりへの耐性の話なので、使い回しをしない・平文で保管しないといった運用面は別途必要です。
技術メモ
HTML1枚(CSS・JavaScript込み、約15KB)で、外部CDNもAPIも使っていません。読み込み後はオフラインでも動きます。
乱数は Web Crypto API の crypto.getRandomValues() を使っています。Math.random() は暗号用途を想定していない擬似乱数で、内部状態から後続の値を推測できる実装があるため、パスワード生成には使えません。
ただし乱数バイトをそのまま文字数で割った余りにすると、偏りが出ます。1バイトは0〜255の256通りで、たとえば候補が88文字なら 256 ÷ 88 = 2 あまり 80 となり、先頭80文字だけが3回、残り8文字が2回割り当てられて出現率が1.5倍違ってしまいます。そこで割り切れない端数の範囲を捨てて引き直しています。
var buf = new Uint8Array(1);
function randInt(max){
var limit = 256 - (256 % max);
for (;;) {
crypto.getRandomValues(buf);
if (buf[0] < limit) return buf[0] % max;
}
}
「各文字種を最低1文字含める」は、まず各文字種から1文字ずつ確保し、残りを全体の候補から埋めたうえで、Fisher-Yates法で並べ替えています。並べ替えないと、先頭が必ず大文字・2文字目が必ず小文字といった規則ができてしまい、探索範囲を絞る手がかりを与えることになります。シャッフルの乱数にも上記の randInt() を使っています。
エントロピーは、候補文字数を n、桁数を L として L × log2 n で計算しています。記号の集合からは引用符・バックスラッシュ・スペースを外しました。設定ファイルやスクリプトに貼ったときにエスケープが要る文字を減らすためです。それでも $ や ! はシェルで解釈されるので、シェルに直接渡す場合はシングルクォートで囲んでください。
コピーは navigator.clipboard を使い、これが使えない環境(httpや古いブラウザ)では textarea と execCommand にフォールバックします。動作環境はPC・スマートフォンのモダンブラウザです。