次の方法で共有


MSDN Online = 10 行シリーズ ~ 10 行でズバリ !! 暗号化 (C#) ~

マイクロソフト株式会社 デベロッパーマーケティング本部
デベロッパーエバンジェリスト 関田 文雄

このコンテンツのポイント
.NET Framework の暗号モデルを理解する。
Triple DES による暗号化を理解する。


今回紹介するコード
1
2
3
4
5
6
7
8
9
10
  private void button1_Click(object sender, System.EventArgs e)
{
	// 文字列を byte 配列に変換します
	byte[] source = Encoding.Unicode.GetBytes(textBox1.Text);
	// Triple DES のサービス プロバイダを生成します
	TripleDESCryptoServiceProvider des = new TripleDESCryptoServiceProvider();
	// 入出力用のストリームを生成します
	MemoryStream ms = new MemoryStream();
	CryptoStream cs = new CryptoStream(ms, des.CreateEncryptor( DesKey, DesIV ),
	                                                    CryptoStreamMode.Write);
	// ストリームに暗号化するデータを書き込みます
	cs.Write(source, 0, source.Length);
	cs.Close();
	// 暗号化されたデータを byte 配列で取得します
	byte[] destination = ms.ToArray();
	ms.Close();
	// byte 配列を文字列に変換して表示します
	textBox2.Text = Encoding.Unicode.GetString(destination);
}

目次
はじめに
作成するアプリケーションの概要
Windows フォーム アプリケーションの開発準備
画面をデザインする
コードを実装する
実行する
おわりに

Visual Basic .NET の内容はこちらに掲載しています。
10 行でズバリ !! 暗号化 (VB.NET)

はじめに

暗号化というと複雑なプログラミングを想像する方が多いかもしれませんが、.NET Framework の暗号モデルは、非常に使いやすく拡張性を持った構成になっていますので、実装が非常に容易です。例えば対称アルゴリズムを実装するには、SymmetricAlgorithm から派生された各対称アルゴリズムのクラスを利用することで、全てのアルゴリズムにおいて同様のプログラミング モデルで暗号化の処理を実装することができます。ここでは、対称アルゴリズムである Triple DES を使って、どのように暗号化を行うか解説します。

作成するアプリケーションの概要

今回作成するのは、テキスト ボックスに入力された文字列を Triple DES により暗号化する Windows フォーム アプリケーションです。 Triple DES で暗号化するためには、あらかじめ対称アルゴリズムで利用する共有キーと初期化ベクタの準備が必要になります。これらの情報を厳密に管理するには、非対称アルゴリズムを利用して通信相手に送信することになりますが、ここでは、1 つのアプリケーションの中で暗号化、復号化を行いますので、アプリケーション起動時に生成し、それをそのまま復号化でも利用します。

Windows フォーム アプリケーションの開発準備

Visual Studio .NET 2003 を起動して、新規にプロジェクトを作成します。
ここでは、"Visual C# プロジェクト" を選択し、"Windows アプリケーション" テンプレートを選択します。"プロジェクト名" テキストボックスに名称を入力したら "OK" ボタンをクリックします。
これで 暗号化を行うアプリケーションの開発準備が完了しました。

図 1. 暗号化を行うためのプロジェクトを新規に作成
図 1. 暗号化を行うためのプロジェクトを新規に作成

画面をデザインする

フォームのデザインは、ドラッグ アンド ドロップという一貫性のある手順で行うことができます。Windows フォームアプリケーションについては「10 行でズバリ !! Windows フォームによるクライアント アプリケーション開発」をご参照ください。
画面左側に表示されている "ツールボックス" の [Windows フォーム] コントロールの中から、Button コントロール、TextBox コントロールをそれぞれ図のように配置します。

図 2. 暗号化を行うためのプロジェクトを新規に作成
図 2. 画面上に コントロールを配置したところ

コードを実装する

using 文を使用して System.Security.Cryptography, System.IO, System.Text ネームスペースを宣言します。この宣言により Principal ネームスペース内のクラス名が暗黙的に解決されます。また、System.Security のアセンブリを参照設定に追加します。

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

次に、"暗号化" ボタンをダブル クリックし、textBox1 の文字列を暗号化する実装を行います。

  private void button1_Click(object sender, System.EventArgs e)
{
	// 文字列を byte 配列に変換します
	byte[] source = Encoding.Unicode.GetBytes(textBox1.Text);

	// Triple DES のサービス プロバイダを生成します
	TripleDESCryptoServiceProvider des = new TripleDESCryptoServiceProvider();

	// 入出力用のストリームを生成します
	MemoryStream ms = new MemoryStream();
	CryptoStream cs = new CryptoStream(ms, des.CreateEncryptor( DesKey, DesIV ),
	                                                    CryptoStreamMode.Write);

	// ストリームに暗号化するデータを書き込みます
	cs.Write(source, 0, source.Length);
	cs.Close();

	// 暗号化されたデータを byte 配列で取得します
	byte[] destination = ms.ToArray();
	ms.Close();

	// byte 配列を文字列に変換して表示します
	textBox2.Text = Encoding.Unicode.GetString(destination);
}

対称アルゴリズムでの暗号化では、ストリームが利用されます。ストリームを利用することで、データ用の中間ストレージも必要とせず、様々なデータ アクセスの手法を提供します。また、対称アルゴリズム、ハッシュアルゴリズムで共通の CryptoStream を利用することで、より使いやすいインタフェースを提供します。

上記のコードでは、対称アルゴリズムの暗号化で利用する共通キー (DesKey 変数) と初期化ベクタ (DesIV 変数) は作成する実装はありません。共通キーと初期化ベクタを厳密に管理するためには、セッション毎に共通キーと初期化ベクタを生成後、非対称暗号化方式を利用して通信相手に送信します。今回は 1 つのアプリケーションの中で復号化を行いますので、まず、アプリケーションのメンバとして、共通キー、初期化ベクタを格納する変数を定義します。

  private byte[] DesKey;
private byte[] DesIV;

次に、初期化時等に以下のコードを実装します。

TripleDESCryptoServiceProvider TDES = new TripleDESCryptoServiceProvider();
DesKey = TDES.Key;
DesIV = TDES.IV;

対称アルゴリズムを利用した暗号化クラスでは、インスタンス生成時、常にキーと初期化ベクタが生成されます。今回、通信相手はいませんので、このキーと初期化ベクタをメンバ変数として格納しておき、復号化の際にも利用できるようにします。

次に "復号化" ボタンをダブル クリックし、textbox2 の文字列を復号化するコードを実装します。

  private void button2_Click(object sender, System.EventArgs e)
{
	// 暗号化された文字列を byte 配列に変換します
	byte[] source = Encoding.Unicode.GetBytes(textBox2.Text);

	// Trippe DES のサービス プロバイダを生成します
	TripleDESCryptoServiceProvider des = new TripleDESCryptoServiceProvider();

	// 入出力用のストリームを生成します
	MemoryStream ms = new MemoryStream();
	CryptoStream cs = new CryptoStream(ms, des.CreateDecryptor( DesKey, DesIV ),
	                                                    CryptoStreamMode.Write);

	// ストリームに暗号化されたデータを書き込みます
	cs.Write(source, 0, source.Length);
	cs.Close();

	// 復号化されたデータを byte 配列で取得します
	byte[] destination = ms.ToArray();
	ms.Close();

	// byte 配列を文字列に変換して表示します
	textBox3.Text = Encoding.Unicode.GetString(destination);
}

見ていただくとわかりますように、復号化も暗号化と全く同じプログラミング モデルになりますので、CryptoStream 生成時の第 2 引数で指定する、変換処理のためのインタフェースを CreateEncryptor から CreateDecryptor に変更することで、復号化のコードを実装できます。

実行する

コードの記述が完了したら、実行してみましょう。
アプリケーションを実行させるには [F5] キーを押すか、[デバッグ] メニューから [開始] をクリックします。"暗号化" ボタンをクリックすることで、上段の文字列が暗号化され、中段に表示されます。"復号化" ボタンをクリックすることで、中段の文字列が復号化され、下段に表示されます。

図 3. アプリケーションを実行しているところ
図 3. アプリケーションを実行しているところ

おわりに

今回は、Triple DES による暗号化をご紹介しました。その他にも DES, RC2, Rijndael アルゴリズムは全く同様のプログラミング モデルを採用していますので、今回の暗号化プロバイダ部分を変更するだけで利用することができます。非対称アルゴリズムとしては、DSA, RSA のアルゴリズムが同様に使いやすいプログラミング モデルで提供されていますので、ご利用の際は、.NET Framework SDK の「暗号サービス」の記述を参考にして下さい。また、実際に暗号化を組み込む際に、非対称アルゴリズムと対称アルゴリズムを組み合わせて利用する際にも、「暗号サービス」の記述をご参考にして下さい。