図1●今回作成するパスワード生成プログラムの実行イメージ
図1●今回作成するパスワード生成プログラムの実行イメージ
[画像のクリックで拡大表示]
リスト1●パスワード生成プログラムのソースコード(VBScript)
リスト1●パスワード生成プログラムのソースコード(VBScript)
[画像のクリックで拡大表示]
レシピ
■ (WSH)Windows Scripting Hostが使える環境

 インターネットを使っていると,あちこちのサイトで会員登録をするはめになりますが,どこもかしこも同じパスワードというのは,セキュリティ上ちょっと恐ろしいものがあります。でも毎回きっちりとパスワードを考えるというのも難しいですよね。じゃあパスワードを自動生成するプログラムを作っちゃいましょう(図1[拡大表示])。

 今回も前回と同様にWindows Scripting Host(WSH)を使って,10分で完成するプログラムのご紹介です。皆様にご用意いただくのはメモ帳ないし手になじんだエディタだけということで,ほかには特別ご用意いただくものはありません。WSHはWindows 98以降,あるいはInternet Explorer 4.0以降をお使いならば,特に何もインストールする必要なく利用できます。

パスワードを作ろう,いや作らせよう

 ID(あるいはユーザー名)とパスワードというのは,セキュリティについて何かとうるさいこのご時勢には欠かせない要素になっています。パスワードを使う機会が増えてくると,どうしても「みんな一緒にしとくか」になりがちです。しかしちょっと待ってください。これはやはり危険というものでしょう。

 職業プログラムの場合には数千人規模の顧客にパスワードを割り当てるといった作業を行わなくてはならないことがあります。1人や2人ならばともかく,数千人に対して意味のない文字列のパスワードを考えて割り当てるという作業。そこで考えました。パスワードを自分が作るのではなくて,パスワードをプログラムに作らせてしまえと。

 リスト1[拡大表示]をメモ帳などで打ち込んで,pass.vbsなどの名前でデスクトップに保存してください。ダブルクリックするとプログラムが動き出します。

KETA = inputbox("何文字のパスワードを作りますか?","パスワードを生成","8")

If KETA < 1 Then
    MsgBox "文字数は0以上でなくてはなりません"
End If

PASS_WRD = "A B C D E F G H J K L M N P Q R S T U V W X Y Z "
MOJISYU_A = MsgBox("アルファベット小文字を使いますか?",vbYesNo)

If MOJISYU_A = vbYes Then
    PASS_WRD = PASS_WRD + "a b c d e f g h i j k m n p q r s t u v w x y z "
End If

MOJISYU_B = MsgBox("数字を使いますか?",vbYesNo)
If MOJISYU_B = vbYes Then
    PASS_WRD = PASS_WRD + "2 3 4 5 6 7 8 9 "
End If

MOJISYU_C = MsgBox("記号を使いますか?",vbYesNo)
If MOJISYU_C = vbYes Then
    '記号
    PASS_WRD = PASS_WRD + "! # $ % & ? - _ ~ @"
End If

'指定された条件で配列を作成
PASS_STR = Split(PASS_WRD)
MAX = Ubound(pass_str)

'指定された桁数のパスワードを生成
For i=0 To KETA - 1
    Randomize
    X = abs(Int((0 - MAX) * Rnd))
    PASS = PASS + PASS_STR(X)
Next
InputBox "パスワードが完成しました","生成完了!",PASS

 このプログラムは最初に「何桁のパスワードを作るか」を聞いてきます。初期値は8桁にしてあります。初期段階では8桁のパスワードを生成する“種”として大文字のアルファベットのみ用意してます。

 桁数を指定すると「アルファベット小文字を使いますか」と聞かれ,その後「数字は?」「記号は?」と3回の問い合わせが出てきます。「はい」と答えればその文字種を含んでパスワードを生成します。「いいえ」と答えた文字種は使用されません。

 文字種を追加したり削除したい場合には「文字[半角スペース]」という書式さえ守っていただければ大丈夫です。この半角スペースは非常に重要で,リスト1の(1)のところの
PASS_STR = Split(PASS_WRD)
の部分に大きくかかわってきます。Splitというのは引数として与えられた文字列を指定された文字種で分割して配列に取り込むという関数です。サンプルのように区切りとなる文字種を指定しない場合,半角スペースごとに分割されて配列に取り込まれます。だからもしAB CDE Fのような書き方をしてしまうと,ABという2文字,CDEという3文字が一つの要素になってしまうため,最初に指定した桁に合わないパスワードができてしまいます。1文字ずつスペースを入れるという約束は守ってください。

 さて,すべてのオプションを指定すると,プログラムは乱数を発生させて,選択要素になっている文字列の中から適当なものを指定された桁数分だけ抽出,合成します。最後に生成されたパスワードが表示されますが,ここはMsgBoxではなくてInputBoxを使っています。コピー&ペーストしたり,出てきたものに細工(気に入らないこともあるでしょう)しやすいですからね。

 このプログラムはオプションで数字が入るように選択したからといって,必ずしも数字が入ってくるわけではありません。「数字が入る可能性がある」です。ランダムに抽出される文字の候補の中に数字が入るけれども,それを含むパスワードの生成を約束するわけではないんですね。ある賞にノミネートはされて会場にはいるけれども,ノミネート=入賞確約ではないというわけです。

ちょっとした配慮が間違いを減らす
チューニングのポイント

 パスワードの種となる文字列には,大文字アルファベットからは「O(オー)と「I(アイ)」が抜いてあります。小文字からは「o(オー)」と「l(エル)」,数字では「0(ゼロ)」と「1(いち)」を抜いています。これらの文字は見分けにくく,正しく打ち込んでいるつもりなのに違っていたということが多々ある文字たちです。

 数字や記号はアルファベット(26文字)に対して数が少ない(数字は10文字)ため,生成後のパスワードでアルファベットよりもどうしても出現頻度が落ちます。これを改善するならば数字は0から9を2回繰り返してデータにしておく(そうすると20個の候補になります),記号は3~4回繰り返してデータにしておくといった細工をしておけばいいでしょう。これで選択された文字種にはほぼ均等に選択される機会が生まれます。

 また記号類についてはサイトなどでは「使用できる記号は−(ハイフン)と_(アンダースコア)だけです」といった制約があるところもあります。その場合は記号類として書かれている文字列の部分を修正してやってください。

 このサンプルはちょっと手を入れていただけばVBAでも使えます。ExcelやAccessで数千人の顧客情報のパスワード欄に,だぁ~とパスワードを埋めていくということもできます。

 拡張についてはいくつか案がありますね。例えば何千件作っても同一パスワードが絶対に存在しないチェックなどがあります。絶対同一がありえないというプログラムにしたい場合は,いったん生成したパスワードをファイルに書き出しておいて,生成ごとに1行ずつ比較し,合致がなければファイル末尾に追加といった流れになると思います。IDが違い,パスワードがここまで無作為なものならば,実際には同一パスワードが1/数千の確率で出てきても危険ということは少ないと思いますけどね。