自分用の安全っぽいパスワードジェネレーター(Windows、bat形式)
Last update 4-16-2025
※ コードの生成にはClaude(3.7 Sonnet)を、コードの評価にはClaudeとChatGPT o3を利用しました(当初、誤ってo1と書いていました)。
※ 生成AIに関連する話題ではないので、別のアカウントを作って再掲するかもしれません。
■ 1. 目的
下記の理由から、手元で実行できる安全なパスワードジェネレーターが欲しくて作りました(経緯は割愛)。
Webブラウザのパスワードジェネレーターは任意のタイミングで利用できない(はず)
パスワード生成のためにインターネット上のサービスを使いたくない(念のため窃取対策はしていたが、手間もかかり良い方法とは言えない)
第三者のアプリにも依存したくない(と考える)
実行してすぐに表示してもらえるだけで良い(早い安いうまい)
(コードを組まなくても何か標準であった気がするが忘れていた)
■ 2. 設計
ClaudeやChatGPTを用いて、下記の流れでブラッシュアップしました(影響の小さい修正を除く)。
コマンドプロンプトの画面上に、ランダムかつ長い英数字からなる文字列を出力させた。
記号を要求するサービスへの対策として文字を追加(全部ではなく自分で選択)して、使用する文字が79種類に増えた。
安全評価を行い、Get-Randomの代わりにRNGCryptoServiceProviderを提案されたので変更した。
任意の箇所を切り取った際に文字数を数えるのが手間なので、文字数を決め打ちして複数個を出力するよう変更した。
■ 3. 最終的なコード
下記のコードをテキストエディタで保存し、「pass_gen.bat」等の任意のファイル名に変更してください。Windows 10と11で動作確認を行いました。
@echo off
echo Generating secure passwords with different lengths...
echo.
powershell -ExecutionPolicy Bypass -Command "$numPasswords = 4; $chars = (48..57)+(65..90)+(97..122)+(33..38)+(40..41)+42+43+(44..47)+95+124+126; $charArray = $chars | ForEach-Object { [char]$_ }; $len = $charArray.Length; $rng = New-Object System.Security.Cryptography.RNGCryptoServiceProvider; $totalChars = (16*$numPasswords) + (20*$numPasswords) + (24*$numPasswords) + (28*$numPasswords); $bigResult = ''; $count = 0; while ($count -lt $totalChars) { $byteVal = New-Object byte[] 1; $rng.GetBytes($byteVal); $val = [int]$byteVal[0]; $max = [Math]::Floor(256 / $len) * $len; if ($val -lt $max) { $index = $val %% $len; $bigResult += $charArray[$index]; $count++ } }; echo '16 characters passwords:'; for ($i = 0; $i -lt $numPasswords; $i++) { echo $bigResult.Substring($i*16, 16) }; echo '' ;echo '20 characters passwords:'; $offset = 16*$numPasswords; for ($i = 0; $i -lt $numPasswords; $i++) { echo $bigResult.Substring($offset + $i*20, 20) }; echo '' ;echo '24 characters passwords:'; $offset = (16*$numPasswords) + (20*$numPasswords); for ($i = 0; $i -lt $numPasswords; $i++) { echo $bigResult.Substring($offset + $i*24, 24) }; echo '' ; echo '28 characters passwords:'; $offset = (16*$numPasswords) + (20*$numPasswords) + (24*$numPasswords); for ($i = 0; $i -lt $numPasswords; $i++) { echo $bigResult.Substring($offset + $i*28, 28) }"
echo.
echo Password generation complete. Press Enter to exit...
pause>nul実行すると、16文字、20文字、24文字、28文字のパスワードを4個ずつ出力します。出力の個数を変えたいときは「$numPasswords = 4」の値を変更してください。
仕様の変更を行いたい場合は、ChatGPTやClaude、Grok等に作り替えさせてみてください。さらに新規のチャットでコードを確認させると、確実性がより高まります。念を入れたい方は、ChatGPT o3(…はやりすぎなのでo4-mini-high)等の高度な推論をご利用ください。
生成はPowerShellを使用しているため、1行にまとめてあります。また、ユーザー権限でも動くと言われましたが未確認です。
■ 4. 実行例
実行するとウインドウが出現して、下記画面のような表示で止まります。好みの箇所をコピーしてご利用ください。当然ながら、下記に表示された文字列を使用することは厳禁です。
使用できない記号が含まれてしまった場合は、長めのパスワードから不要な文字を削除すると良いでしょう。それでも足りない場合は出力し直すか、次の行の先頭から順に拾ってください(恣意的ではなく、機械的に行うことが大事)。

■ 5. パスワードの安全性の評価(仮)
ChatGPT o3にコードを渡して評価させました。ランダムな文字で構成されたパスワードの場合、使用する文字が79種類と長さが16~28文字では、総当たり攻撃に対して(のみ)十分な強度があるとみられます。
16文字(約100ビット)でも相当強力
一般的なWebサービスでの利用や個人用ファイルの保護など、多くの用途には十分以上の強度と考えられます。
20文字(約126ビット)以上はさらに安全マージンが大きい
20文字から上は 2^100 を優に超える総当たり空間になり、コンピューターでのブルートフォース攻撃は事実上不可能な領域になっていきます。長めのパスワードを扱えるサービスや環境であれば、20文字以上を推奨すると安心です。
24文字(約151ビット)・28文字(約176ビット)は極めて堅牢
これらは「将来の計算機リソース増大」をある程度考慮しても、一部の国家レベル攻撃を想定しない限りは過剰なまでに安全な強度となるでしょう。
ビットという単位が出てきましたが、これはパスワードのエントロピーで、「log₂ ([character set size] * [password length])」で計算できます。たとえば、括弧内の値(組み合わせの個数)が256であれば、エントロピーは8 bitsとなります。
79 (set sizes) の場合:
16 (length) で 100.86 bits
20 (length) で 126.08 bits
24 (length) で 151.29 bits
28 (length) で 176.51 bits
上記は、本記事のパスワードジェネレーターが生成するパスワードのエントロピー(理論値)です。79種類の文字を用いたランダムな文字列を出力しますので、「パスワードが16文字の場合、パスワードの組み合わせの個数は2の100.86乗個ある」ということになります。
下記は計算に使ったバッチファイルです。長さが8文字から32文字までのエントロピーを計算します。文字の種類の数は、79の部分を書き替えると変更できます。
@echo off
echo Calculating password entropy for character set with 79 characters...
echo.
powershell -ExecutionPolicy Bypass -Command "$charsetSize = 79; echo 'Password length | Entropy (bits)'; echo '---------------|---------------'; for ($length = 8; $length -le 32; $length++) { $entropy = [Math]::Log($charsetSize, 2) * $length; $formattedEntropy = '{0:F2}' -f $entropy; echo ('{0,14} | {1,15}' -f $length, $formattedEntropy) }"
echo.
echo Entropy calculation complete. Press any key to exit...
pause > nulバッチファイルからPowerShellを呼び出すと他のプログラミング言語に依存しなくなるので(Windowsには依存する)、簡単な処理の場合は良いですね。コードはLLMが作ってくれますし。
■ 6. パスワードの安全性の評価(未完の完)
鉄板とも言える、NISCの資料を確認してみたところ、端的な結論を表した図にこのような記述がありました。
ログイン用パスワードは、長くすることでより安全に
「数字+英大文字+英小文字」の8桁だと→約 218 兆通り
「数字+英大文字+英小文字」の12桁だと→約32垓通り
同じ文字種でも、パスワードを長く設定することで推認されにくくなります。
https://security-portal.nisc.go.jp/guidance/handbook.html
第一章 3.2 パスワードの安全性を高める
より
以前は「パスワードの文字は何種類の文字で何文字以上を推奨」との記述があったようですが、現在はそのような記述が見つかりません。
とはいえ、ファイルの暗号化等におけるパスワードは現存しますし、多要素認証が採用されていない(または利用していない)場面もあるかと思います。よって、十分な強度を持ったパスワードを適切な方法で管理する必要性はまだ失われていません(管理の方法は各自でご確認ください…)。
近年トレンドになっているのは、独自のルールを用いて、文字列を組み合わせたり一部を編集したりして、長いパスワード作成する方法です。ただし、たとえパスワードが推測困難になったとしても、何らかの方法で盗まれたり無効化されたりしては意味がありません。
現代において推奨されるパスワードのポリシーについて、信頼できそうなソースが無いか調べてみました。しかし残念ながら、Web上には旧来のポリシーを挙げる例ばかりが出てきます。古い情報は見ないようにしましょう。
個人的には、79種類の記号込みの文字を使ったランダムなパスワードの場合は16文字で実用レベル(不足のない強度)、18~20文字であれば将来にわたって安全(非常に強固)と、現時点では結論づけることにします。現実として、そこまで要求される例があまり無いのも理由の1つです。
また、たとえパスワードが狙われたとしても、総当たり攻撃が成功するよりも先に、
アカウントが無効化または削除されて利用できなくなる
パスワードで守りたい対象の賞味期限が切れる
パスワードで守りたい対象の持ち主がこの世を去る
のいずれかになると考えます。
いい加減な締めになってしまいましたが、現実としてこれで十分だと思います。ですよね?
■ 7. その他
私が書いた他の記事は、メニューよりたどってください。
記事に関することで何かありましたら、Xの@riddi0908までお願いします。
