パスワード管理ツールを自作しよう!(番外編・パスワード生成の追加編)

C#入門
この記事は約11分で読めます。

これまでに、パスワード管理ツールの自作について8回に分けてソースコードを解説しました。

今回は、バージョンアップということで、パスワード管理ツールに乱数を使ったパスワード生成機能を追加したいと思います。

今回は最後にサンプル動画を用意しましたので、細かい部分はそちらも参考にして頂ければと思います。

機能追加の概要

パスワード管理ツールの追加する機能は次の通りです。

  • 編集ボタンをクリックすることで、指定した長さのランダムなパスワードを生成する
  • 英大文字、小文字、数字、記号を含むランダムなパスワードを生成する。

編集ボタンをクリックすることで、下記のレイアウトになります。

別のウィンドウを表示して、パスワードを構成する文字の種類が指定できるなどの機能も考えましたが、分かりやすさを優先して、今回はシンプルな仕様にしました。

パスワード生成機能の有効/無効の制御は、編集モードと参照モードの切り替えと考え方は同じで、DataGridViewのReadOnlyプロパティの値を見て有効/無効を設定します。

あと、パスワード生成のクラスを使うため、System.Webの参照設定を行っている点がポイントです。

それでは、ソースコードの説明を始めたいと思います。

ソースコード

まず、全体のソースコードを掲載しておきます。

尚、今回のVisual Studio 2019 プロジェクトファイルは、下記からダウンロード可能です。

参照設定

最初は乱数を使ってパスワードを生成しようと思っていたのですが、パスワード生成が簡単に出来るクラスがあったので、これを使うことにしました。

その為、参照設定という作業が必要になります。

  1. Visual Studio 2019 の右端にある「ソリューションエクスプローラー」から「参照」を右クリックします。
  2. 表示されるメニューから「参照の追加」をクリックすると、「参照マネージャ」のウィンドウが表示されます。
  3. 左端の「アセンブリ」をクリックすると表示される名前一覧から「System.Web」を探し、クリックします。
  4. 左端のチェックボックスにチェックが入ったことを確認し、最後にOKボタンをクリックしてください。

以上で、参照設定が完了します。

参照設定が正しく行われたか否かは、「参照」の▹マークをクリックし、表示される一覧の中に「System.Web」が表示されているか否かで確認できます。

参考動画の2分あたりに参照設定の操作がありますので、必要に応じてご覧ください。

追加内容

では、具体的な追加内容について解説していきます。

usingの指定

まず冒頭にある一連のusing の最後に、下記の1行を追加しています。

これで、後述するパスワード生成クラスが利用できるようになります。

デザイン変更

パスワード生成を行うために、以下のコントロールを張り付けています。

用途コントロール名
パスワード文字数の入力欄uxPasswordLength
パスワード生成ボタンuxGenaratePassword
上記2つのコントロールの
表示/非表示切り替え用
uxGenaratePasswordPanel

パスワード文字数の入力欄とパスワード生成ボタンは、直接MainFormに張り付けても良かったのですが、Panelコントロールを張り付けてから、その上にこれら2つのコントロールを張り付ける方法を採用しました。

パスワード文字数の入力欄とパスワード生成ボタンは、編集モードの時に表示され、それ以外は非表示にするという制御を行います。

Panelに対して表示/非表示設定を行うと、Panelの上に張り付けられたコントロールはそれに連動して表示/非表示となるため、複数個のコントロールを一括制御する場合はPanelを使う方が楽なのです。

画面レイアウトが終わったら、パスワード生成ボタン「乱数」をダブルクリックして、イベントハンドラを作っておいてください。

今回追加するイベントハンドラは、これだけです。

パスワード生成ボタンについて

パスワード生成ボタンの表記が「乱数」となっていますが、これはちょっとしたミスです。

すみません。

もともと、乱数を使ってパスワードを生成するつもりだったのですが、パスワード生成に便利なクラスがあったので、これを使う事にしました。

その際、ボタンの表記を「生成」にすべきだったのですが、修正するのを忘れて動画を作成したので、このままにしています。

ボタンの表記、レイアウトを含めて好きなように変更して頂ければと思います。

MainForm コンストラクタへの追加

コンストラクタには、次の4行を追加しました。

uxPasswordLength.Text は、単純にパスワード文字列長の初期値に8を設定しています。

Textプロパティは string 型なので、数字の8ではなく、文字列の8を代入するため、”8″ としています。

また、TextAlignプロパティにHorizontalAlignment.Right を設定しているのは、右寄せしたかったからです。

次に、uxGenaratePasswordPanelの位置が入っているLocationプロパティに対して、「パスワード取得」ボタンの位置を 代入しています。

こうすることによって、Panelコントロールをレイアウトエディタのどこに置いても、実行時には「パスワード取得」ボタンの位置に移動するようになります。

もちろん、レイアウトエディタ上で、最初から「パスワード取得ボタン」の上にPanelコントロールを置いてもOKです。

ただ、将来プログラム変更をする際に「パスワード取得ボタン」が隠れていると変に悩んでしまうかもしれません。

そこで、あえて位置をずらしてレイアウトし、実行時に位置合わせするようにしました。

追加した4行目は、パスワード生成パネル(uxGenaratePasswordPanel)を非表示にするコードです。

全てのコントロールには、 visibleというプロパティがあって、ここに false を代入すると非表示になります。

これが無いと、「パスワード取得ボタン」が隠れてしまい、押せなくなってしまいます。

尚、これらの初期値設定は、コードを書かずにVisual Studio のプロパティウィンドウからの設定も可能です。

編集ボタンクリック時のイベントハンドラへの追加

UxEditMode_Clickイベントハンドラは、DataGridViewのReadOnlyプロパティの値に応じて、画面のレイアウト(編集ボタンの表記、背景色の設定)を変更するコードを書いています。

今回、ReadOnlyの状態に応じて、パスワード生成パネルの表示/非表示を切り替えるコードを書きました。

uxIdPasswordGrid.ReadOnly が true の時は、uxGenaratePasswordPanelを非表示にしたいので、visibleプロパティにfalse を代入しています。

uxIdPasswordGrid.ReadOnly が false の時は、uxGenaratePasswordPanelを表示したいので、visibleプロパティに true を代入しています。

このイベントハンドラへの変更は、この2行の追加だけとなります。

パスワード生成ボタンのイベントハンドラ追加

パスワード生成ボタンは今回追加したものなので、クリックされた時のイベントハンドラも新しく追加しています。

やりたい事は、画面から入力されたパスワード長を読み込んで、その文字数だけパスワードを生成するという内容です。

ここで新しいことが2点登場します。

1つは画面から入力された文字を数値として取得する方法と、パスワードを生成する方法です。

パスワードの文字列長は uxPasswordLength のTextプロパティに入っていますが、これはあくまで文字列、つまりstring 型です。

パスワード生成クラスは MembershipクラスのGeneratePasswordメソッドを使う事で取得できますが、このメソッドには数値、つまり int 型の文字列長を指定しなければなりません。

そこで、文字列から数値への変換が必要になります。

文字列を数値に変換するには

単に変換するだけなら、それぞれの型にはParseメソッドが搭載されているので、これを使えば済みます。

例えば、文字列としての数値を int型の数値にに変換するなら、 int.Parse()を、実数型の数値に変換するなら、double.Parse()を使うことで完了します。

C#に用意されている全ての型は、実はクラスなので、様々なメソッドが用意されており、Tryメソッドもその中の1つです。

ただし、Tryメソッドには問題もあります。

それは、数値以外の文字が混ざっている場合、例えば “12ab” なんかだとエラーになるのです。

その対応方法として、変換できるか否かを最初にチェックし、変換できるなら値を返すという TryParse メソッドが用意されています。

そこで、今回はこれを使う事にしました。

メソッドの戻り値は1つしか返せませんので、TryParseでは変換に成功したか否かを示す true/false が返されます。

変換した結果は、 第2引数に指定した val 変数に返されます。

ここで、 out val という記述をしていますが、これはC#のルールです。

通常、引数として渡された値は、メソッドの中で変更しても、呼び出し側には反映されません。

しかし、out を付けることで、メソッドの中で変更した結果を、引数に反映することが可能です。

勿論、何でもかんでもそうなるのではなく、out を付加された引数を受け取れるよう、メソッド側で特別な記述をしなければなりません。

TryPhaseメソッドは、それに対応しているメソッドなのです。

3項演算子とは

ここでもう1つ説明すべきことがあります。

それは、3項演算子です。

(条件) ? 式1 : 式2

という風な書き方をすると、条件が true の場合は 式1を、false の場合は 式2を実行して、結果を返してくれます。

と書いていますが、これはTryParseの結果が true なら、TryParseの第2引数に返された val の値を len に代入し、false なら 8を代入するという意味になります。

通常の if 文を使うのであれば、

の様に記述することになりますが、3項演算子だと1行で書けてしまうので、C#では良く使われます。

ちなみに、TryPhaseを使うには、あらかじめ結果を受け取る変数を定義する必要がありますが、TryPahseの中で受け取る変数を定義してしまう方法もあります。

②の方法だと、事前記述した int val を無くすことが可能です。

パスワード生成

パスワードを生成する部分は以下のクラスとメソッドを使います。

System.Web.Security.Membership.GeneratePassword(引数1、引数2)

ソースコードの冒頭に

を記述しましたが、これをすることで System.Web.Securityを省略できるようになるので、

Membership.GeneratePassword(引数1、引数2)

という記述で済みます。

1か所しか記述しないのであれば using は不要かもしれませんが、複数個所記述するのであれば、 using をしておく方が楽になります。

さて、この GeneratePassword メソッドには、第1引数として「生成するパスワードの長さ」を、第2引数として「最低限、区切り記号を含ませる個数」を指定します。

今回は 第1引数に画面から入力された値、第2引数に0を指定しています。

第2引数に0を指定すると、「パスワードに区切り記号が全く含まれない可能性がある」という意味だけなので、区切り記号が含まれることも十分あり得ます。

3を指定すると、「パスワードに区切り記号が最低3個含まれる」という意味になります。

パスワード生成をする前に if文で len が 123以下であることを確認していますが、これはMembership.GeneratePasswordの第1引数が128を超えるとエラーになるためです。

そして、最後に生成したパスワードを DataGridView のカレント行の「パスワード」列に代入しています。

DataGridViewへの代入の仕方が、今までと少し変わっていますが、実は複数の代入方法があります。

どちらの方法を使っても同じなのですが、今回は新しい方法を紹介しました。

レイアウト変更と参照設定の動画

最後に、レイアウト変更と参照設定についての参考動画を掲載しておきます。

参照設定の方法は2分後あたりから登場します。

まとめ

如何でしたでしょうか。

前回作ったパスワード生成ツールに、パスワード生成機能を追加してみました。

このように、使いながら必要な機能を追加していけるのが、自分で作ることのメリットであり、DIYの醍醐味です。

最初は試行錯誤するかもしれませんが、是非自分で作ったプログラムをバージョンアップしていってください。

タイトルとURLをコピーしました