*

[C#]パスワード暗号化プログラムの初歩

公開日: : C#, プログラミング

パスワード暗号化の初歩的方法。
子供だましみたいなプログラムですね。
これは入社四か月の頃にプロダクトキー作れっていう無茶振りされたときに暗号化の練習をしていたときのソースです。
実際のプロダクトキーは更に捻りを加えております。

どこぞのソニーピクチャーズさんでパスワード流出とか聞いて、思い出したので、記載。
ちなみにPasswordっていうフォルダパスワードが保管されてて、暗号化もしてなかったとか。

◆全文

using System;
using System.Collections.Generic;
using System.Security.Cryptography;
using System.Text;
using System.IO;

namespace WannabeNote {
	class EncryptPassword {
		private const string DesIV = @"TEKITONASYOKIVEC";	//初期化ベクトル
		private const string DesKey = @"TEKITONAANDOUKEY";	//暗号キー
		private const string PassWordFilePath = @"C:\Hoge\Password.txt";	//絶対にこんな名前のファイルを作っちゃ駄目です。
		
		public void WritePassword(string inputText) {
			WritePassword(Encrypt(inputText));
		}
		
		private void WritePassword(byte[] inputByteSet) {
			using (FileStream fs = new FileStream(PassWordFilePath, FileMode.Open, FileAccess.Write)) {
				fs.Write(inputByteSet, 0, inputByteSet.Length);
				fs.Close();
			}
		}
		
		private byte[] ReadPassword() {
			byte[] byteSet = null;
			using (FileStream fs = new FileStream(PassWordFilePath, FileMode.Open, FileAccess.Read)) {
				byteSet = new byte[fs.Length];
				fs.Read(byteSet, 0, byteSet.Length);
				fs.Close();
			}

			return byteSet;
		}

		public bool CheckPassword(string inputText) {
			byte[] byteSet = ReadPassword();
			string strDat = Decrypt(byteSet);
			bool b = strDat.CompareTo(inputText) == 0 ? true : false;

			return b;
		}
		
		private byte[] Encrypt(string text) {
			RijndaelManaged rijndael = new RijndaelManaged();

			rijndael.IV = Encoding.UTF8.GetBytes(DesIV);
			rijndael.Key = Encoding.UTF8.GetBytes(DesKey);
			
			byte[] strBytes = Encoding.UTF8.GetBytes(text);
			byte[] encBytes = null;
			using (ICryptoTransform encryptor = rijndael.CreateEncryptor()) {
				encBytes = encryptor.TransformFinalBlock(strBytes, 0, strBytes.Length);			
			}

			return encBytes;
		}

		private string Decrypt(byte[] strBytes) {
			RijndaelManaged rijndael = new RijndaelManaged();

			rijndael.IV = Encoding.UTF8.GetBytes(DesIV);
			rijndael.Key = Encoding.UTF8.GetBytes(DesKey);

			byte[] decBytes = null;
			using (ICryptoTransform decryptor = rijndael.CreateDecryptor()) {
				decBytes = decryptor.TransformFinalBlock(strBytes, 0, strBytes.Length);
			}

			return Encoding.UTF8.GetString(decBytes);
		}
	}
}

◆解説

private const string DesIV = @"TEKITONASYOKIVEC";	//初期化ベクトル
private const string DesKey = @"TEKITONAANDOUKEY";	//暗号キー
private const string PassWordFilePath = @"C:\Hoge\Password.txt";	//絶対にこんな名前のファイルを作っちゃ駄目です。

暗号化のための初期化ベクトルと暗号キーを定数でとりあえず持ってます。
あくまでの暗号化の手法の練習なので、本番では絶対にこんな定数をソース平文に書いちゃ駄目です。
デコンパイルされたらあっさりパスワードが破られてしまいます。
Password.txtなんてもっての外。普通はDBとかで管理すると思います。

public void WritePassword(string inputText) {
	WritePassword(Encrypt(inputText));
}
		
private void WritePassword(byte[] inputByteSet) {
	using (FileStream fs = new FileStream(PassWordFilePath, FileMode.Open, FileAccess.Write)) {
		fs.Write(inputByteSet, 0, inputByteSet.Length);

		fs.Close();
	}
}

暗号化したパスワードをファイルに書き込むところ。
オーバーロード

private byte[] ReadPassword() {
	byte[] byteSet = null;
	using (FileStream fs = new FileStream(PassWordFilePath, FileMode.Open, FileAccess.Read)) {
		byteSet = new byte[fs.Length];
		fs.Read(byteSet, 0, byteSet.Length);
		fs.Close();
	}

	return byteSet;
}

逆にパスワードを読み込むところ。

public bool CheckPassword(string inputText) {
	byte[] byteSet = ReadPassword();
	string strDat = Decrypt(byteSet);
	bool b = strDat.CompareTo(inputText) == 0 ? true : false;

	return b;
}

入力されたパスワードを復号した文字列と比較してます。
string strDat = Decrypt(byteSet);が復号しているところですね。
Decryptについては後述。

private byte[] Encrypt(string text) {
	RijndaelManaged rijndael = new RijndaelManaged();

	rijndael.IV = Encoding.UTF8.GetBytes(DesIV);
	rijndael.Key = Encoding.UTF8.GetBytes(DesKey);
			
	byte[] strBytes = Encoding.UTF8.GetBytes(text);
	byte[] encBytes = null;
	using (ICryptoTransform encryptor = rijndael.CreateEncryptor()) {
		encBytes = encryptor.TransformFinalBlock(strBytes, 0, strBytes.Length);			
	}

	return encBytes;
}

パスワードの暗号化部分です。
Rijindealというアルゴリズムです。
Rijindealについては話が長くなるので、コーダーレベルならブラックボックスで構わないと思います。
usingを利用していますが、利用しないならDispose()してあげてください。

private string Decrypt(byte[] strBytes) {
	RijndaelManaged rijndael = new RijndaelManaged();

	rijndael.IV = Encoding.UTF8.GetBytes(DesIV);
	rijndael.Key = Encoding.UTF8.GetBytes(DesKey);

	byte[] decBytes = null;
	using (ICryptoTransform decryptor = rijndael.CreateDecryptor()) {
		decBytes = decryptor.TransformFinalBlock(strBytes, 0, strBytes.Length);
	}

	return Encoding.UTF8.GetString(decBytes);
}

復号化部分です。
Rijindealで暗号化したならRijindealで復号しましょう。

◆まとめ
パスワードが流出しても、実際に不正アクセスされる前に、パスワードを変更してしまえば、被害を最少にすることが出来ます。
パスワードを暗号化する理由は、流出したときに、解析される前にパスワード変更をしてしまえ、というものだと私は思います。
Passwordというフォルダ(なんでフォルダなんだろう)にパスワードを保管しておくのは閉口する部分もありますが、概ねは構わないとは思います。

ad

関連記事

wannabenote

[Visual Studio]いつもの文章をコピペするぐらいならSnippetizer使いませんか

Visual StudioのSnippetizerって使ってますか。 あれ? 意外に知らん人多いの

記事を読む

Unity_

[Unity]Unity2Dチュートリアル スプライトを利用する その2

前回で、タイルを置いて、全部消えちまうじゃねぇか! 色一個一個つけるのめんどくせぇ!! というところ

記事を読む

logo

[VSTO,Excel,C#]C#のアドインで現在起動しているExcelを取得する。

ExcelのアドインをC#で開発してるんですが、情報少ないですねぇ。 とりあえずMicrosoft

記事を読む

logo

[C#,Access]microsoft AccessにODBC接続する

「client AccessのODBC」というタイトルのために、AccessのODBC接続を知りたく

記事を読む

Unity_

[Unity]Unity2Dチュートリアル 画面上のGameObjectを取得する

前回の続きです。 というわけで移動の仕方は完璧です。本当なら一瞬で移動ではなく、パズドラみたく

記事を読む

cwbx.dll 参照の追加

[C#,AS400]C#でAS400のプログラムCallとコマンドの実行方法。

PCのプログラムからCall AS400のRPGPGMをPCから呼び出ししたいときがあります。

記事を読む

socket p2p unity

[Unity]Socket通信でP2Pすっぞ ホストへ接続

前回はホストが待ちうけするところまで作りました。 今回はクライアントがホストへ接続できるように

記事を読む

logo

[C#, AS400]列挙体の文字列化&DB2/400にODBC接続

定数をなるべく書きたくないんです。 あとからメンテをするときに複数箇所変更しなくてはいけないから。

記事を読む

wannabenote

[C#, Excel]最終行を取得する

Excelを触っているのでC#でExcelネタが続きます。 Excelの行数が知りたい Exce

記事を読む

logo

[Unity]GameObject.Findは遅い

遅いらしいです。 なので、マネージャークラスを作りましょう、というのが風潮らしいです。 マネージ

記事を読む

ad

Message

メールアドレスが公開されることはありません。

次のHTML タグと属性が使えます: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code class="" title="" data-url=""> <del datetime=""> <em> <i> <q cite=""> <strike> <strong> <pre class="" title="" data-url=""> <span class="" title="" data-url="">

ad

  •  Auther;わなび

     「オープン系得意だよね? 俺のPCの調子悪いんだけど」という無茶振りから解き放たれゲームエンジニアに。
    C#とかUnityを扱います。
    Twitterフォロー大歓迎です。
    githubアカウント→wannabenote
  • follow us in feedly
PAGE TOP ↑