System.Security.Cryptography 名前空間
対称暗号化方式
□ SymmetricAlgorithm クラス
├─□ DES クラス
│ └─□ DESCryptoServiceProvider クラス
├─□ RC2 クラス
│ └─□ RC2CryptoServiceProvider クラス
├─□ Rijndael クラス
│ └─□ RijndaelManaged クラス
├─□ TripleDES クラス
│ └─□ TripleDESCryptoServiceProvider クラス
└─□ Aes クラス
├─□ AesCryptoServiceProvider クラス
└─□ AesManaged クラス
対称暗号化方式では、暗号化と復号化に同じ鍵を使用する。対称暗号化方式は、主にコンテンツデータの暗号化・復号化使用される。そのため、非対称暗号化方式とは異なり、ストリーム (CryptoStream クラス) を使用して暗号化・復号化を行う方式が採用されている。
SymmetricAlgorithm クラスの Mode プロパティには、暗号化に使用するブロック暗号モード (CipherMode 列挙体) を指定することができる。
Aes クラス及びその派生クラスは、.NET Framework 3.5 より追加されたクラス。
非対称暗号化方式
□ AsymmetricAlgorithm クラス
├─□ DSA クラス
│ └─□ DSACryptoServiceProvider クラス
├─□ RSA クラス
│ └─□ RSACryptoServiceProvider クラス
├─□ ECDiffieHellman クラス
│ └─□ ECDiffieHellmanCng クラス
└─□ ECDsa クラス
└─□ ECDsaCng クラス
非対称暗号化方式は、暗号化と復号化に異なる鍵を使用する。非対称暗号化方式による暗号化は、主に電子署名に使用される。また、対称暗号化方式による暗号化データの通信を開始する際に、共通鍵を通信相手に渡すためにも使用される。
RSACryptoServiceProvider クラスは暗号化を行う Encrypt メソッドと、復号化を行う Decrypt メソッドを提供しているが、公開鍵での暗号化, 秘密鍵の復号化しか行えず、秘密鍵での暗号化, 公開鍵の復号化は行えない。これは、通常、公開鍵は誰でも入手可能であるため、暗号化通信においては秘密鍵による暗号化が意味を持たないためだと思われる。
電子署名はこの性質を逆手に利用しており、暗号化に秘密鍵を使用する。電子署名を行うには SignData メソッドや SignHash メソッドを使用し、電子署名の検証には VerifyData メソッドや VerifyHash メソッドを使用する。
ECDiffieHellman クラス及びその派生クラス、ECDsa クラス及びその派生クラスは、.NET Framework 3.5 より追加されたクラス。
ハッシュアルゴリズム
□ HashAlgorithm クラス
派生クラス多いし、気が向いたら補完。。。
各具象クラスの名前
CryptoServiceProvider 系は、CAPI (Cryptographic Application Programming Interfaces) 実装。
Cng 系は、CNG (Cryptography Next Generation) 実装。
Managed 系は、マネージド実装。
電子署名にはいくつか種類があるが、RSA暗号化方式を用いた電子書名が特に有名である。
この記事では、RSA暗号化方式について解説する。
[ RSA暗号化方式 ]
公開鍵基盤(PKI)のひとつ。
秘密鍵と公開鍵という2種類の鍵と、電子証明書から成る。
RSA以外にもDSA等の方式があるが、RSAと他の方式では、秘密鍵と公開鍵の性質や署名の生成方法等が異なるので注意。
[ 電子証明書 ]
電子的な身分証明書。信頼できる第三者(認証局)に発行してもらう。
電子証明書には、認証局の電子証明書によって電子署名が施される。これにより、信頼できる第三者が発行したことが証明される。
認証局に発行してもらった電子証明書には秘密鍵と公開鍵が含まれている。また、他者に公開するためには、公開鍵のみを含んだ電子証明書を公開する。
実は、電子署名の発行は専用のツール(無償で入手可能)さえあれば誰にでもできる。自分自身の電子証明書を作ることも可能で、これは一般に「オレオレ証明書」と呼ばれていて、通常、この証明書には信頼性が全くない。
日本では、2001年4月1日から電子署名法が施行された。これにより、認定を受けた認証業務 (総務大臣,経済産業大臣,法務大臣の認定を受けた電子証明書発行サービス) で発行してもらった電子証明書による電子署名は、法的な効力を持つ。(発行は有償。また、電子証明書には有効期限がある。)
電子証明書はいくつも種類があり、どれを(どの認証局で)購入すればいいかは利用目的により異なる。
[ 秘密鍵と公開鍵 ]
秘密鍵は本人以外の手に渡ってはいけないもので、本人が厳重に保管する必要がある。
公開鍵は本人以外に公開してよいものである。
秘密鍵と公開鍵は暗号化・復号化を行うためのものである。
秘密鍵と公開鍵は対になっていて、秘密鍵で暗号化したデータは公開鍵でのみ復号化でき、公開鍵で暗号化したデータは秘密鍵でのみ復号化できる。
[ 電子署名 ]
データに対する電子的な署名。
電子署名は、対象のデータのハッシュ値を秘密鍵で暗号化したものである。
電子証明を公開鍵によって復号化した値と、対象データのハッシュ値を比較することで、 データ改竄の有無を調べることができる。
exeファイルやdllファイル、pdfファイル等では、電子署名をファイルに埋め込むことができる。
だが、jpegファイルなどではファイルに埋め込むことができないので、電子署名は独立した一つのファイルとなる。
電子署名は、データの正当性と署名を行った人物を証明する。しかし、署名を行った日時を証明することはできない。日時の証明には「タイムスタンプ」という技術 を利用する。 (タイムスタンプも電子署名を利用した技術である。簡単に説明すると、対象のデータのハッシュ値に国際原子時を加えたものに電子署名を行ったものがタイムスタンプとなる。)
一般的に、共有DLLには、署名を行うことが推奨される。
GACにインストールするDLL、ClickOnceのアプリケーション マニフェストと配置ファイルには、署名が必須となる。
また、一般的に、EXEファイル、一つのアプリケーション固有のDLLには、署名を付けないことが推奨される。
【 アセンブリの署名による利点 】
アセンブリの署名により、主に以下のような効果が得られる。
[ 1. DLLをGACにインストールできる ]
GACとは、一台のPC内で、グローバルに参照できる特殊な領域のことである。GACにインストールされたDLLは、一台のPC内で共有される。
具体的な場所は、 [ %SystemRoot%\assembly ] となる。 [ %SystemRoot% ] は、Windows XPなら通常 [ C:\WINDOWS ] を示す。
GACへのインストールは手動ででき、単にDLLをGACへドラッグ&ドロップするだけでインストールされる。また、グローバル アセンブリ キャッシュ ツール (Gacutil.exe) を使ってインストールすることもできる。Gacutil.exeを使ってインストールするには、.NET Framework付属のコマンドプロンプトで以下のコマンドを実行する。FileNameには、DLL名を記述する。gacutil /i FileNameなお、.NET Framework クラスライブラリ (以降、NFCと表記) も、ここにインストールされている。
[ 2. DLLのバージョン管理が行える ]
例えば、.NET Framework (以降、.NET Fxと表記) 1.1のNFCは、バージョン1.0.5000.0で、.NET Fx 2.0のNFCはバージョン2.0.0.0であるが、これらはGAC内に共存できる。
これらが共存しているPCで、.NET Fx 1.1をベースに作成されたアプリケーションを実行するとどうなるか?答えは、バージョン1.0.5000.0のNFCが利用される。つまり、バージョンの異なるDLLが存在しても、アプリケーションは決められたバージョンのDLLを利用するということである。
DLLのバージョン管理が行われることで、DLL Hellが解消されるという利点が得られる。
なお、バージョン管理は、GAC内のDLLに限らず、アプリケーションのインストールディレクトリ内のDLLにも適用される。
(実は、NFCは下位互換性があり、また特別なので、.NET Fx 1.1がインストールされていない場合、.NET Fx 1.1ベースのアプリケーションは.NET Fx 2.0上で動き.NET Fx 2.0のNFCを利用するわけだけど^^; )
[ 3. アセンブリの改竄を検出できる ]
これは電子署名そのものの性質 (詳しくは次回) でもある。
アセンブリを誰かが勝手に改竄した場合、アプリケーションの実行時にそれを検出することができる。
この利点が、ある意味一番大きな利点かもしれない。
ただし、署名に使った秘密鍵が第三者の手に渡らないことが大前提である。署名に使った秘密鍵さえあれば、改竄した後に再び署名を行うことができてしまうため、秘密鍵は厳重に保管しなければならない。
【 アセンブリに署名を行う方法 】
アセンブリに電子署名を行うには、RSA暗号化方式 (詳しくは次回) の秘密鍵と公開鍵という、対になった鍵 (以降、キーペアと表記) が必要である。
キーペアを作成し、キーペアを元にアセンブリに署名する手順を以下に記述する。
[ 従来からの方法 ]
.NETでは、キーペアを作成するためのツールとして、厳密名ツール (Sn.exe) が提供されている。
使用方法は簡単で、.NET Framework付属のコマンドプロンプトで以下のコマンドを実行すれば、キーペアがファイルとして作成される。outfileには、出力ファイル名を記述し、拡張子は.snkとする。sn -k outfileキーペアファイルをキー コンテナという特殊なファイルに格納する場合は、続けて以下のコマンドを実行する。infileには作成したキーペアファイルの名前、ContainerNemaにはキー コンテナの名前を記述する。 (キー コンテナに拡張子はない。)sn -i infile ContainerName
キーペアを作成したら、アセンブリに署名を行う。署名を行うには、アセンブリ リンカ (Al.exe) を利用するか、AssemblyKeyFileAttribute (キーペアをキーコンテナにインストールした場合はAssemblyKeyNameAttribute) を使用する。
アセンブリリンカを使う場合は、アセンブリファイルではなくモジュールファイル(拡張子は.netmodule)が必要となるため、C#コンパイラを使って自分でコンパイルを行うことになる。この辺は、@ITさんの以下の記事が参考になる。
@IT:インサイド .NET Framework [改訂版]第1回 マネージ・コード/アセンブリ/モジュール
属性を使う場合は、以下のコードを (通常、AssemblyInfo.csに) 記述するだけでよい。[assembly: AssemblyKeyFile("FileName")]キーコンテナにインストールした場合は、以下のコードとなる。[assembly: AssemblyKeyName("ContainerName")]
ただし、NET Framework 2.0 では、AssemblyKeyFileAttributeやAssemblyKeyNameAttributeによるアセンブリの署名は、セキュリティ上の問題等を理由に非推奨となっている。
[ Visual Studio 2005 での署名 ]
Visual Studio 2005では、キーペアの作成からアセンブリの署名までを、簡単に行うことができるようになった。手順は以下のようになる。
- ソリューション エクスプローラでプロジェクトの右クリックメニューの [ プロパティ ] をクリックし、プロジェクト デザイナを開く。
- [ 署名 ] タブをクリック。
- [ アセンブリの署名 ] チェックボックスにチェックを付ける。
- コンボボックスの [ <新規作成...> ] を選択する。
- [ キー ファイル ] テキストボックスに、作成するキーペアファイルの名前 (拡張子は不要) を入力する。
- パスワードで保護する場合は、[ キーファイルをパスワードで保護する ] にチェックを付け、8桁以上のパスワードを入力する。保護しない場合は、チェックを外す。
- [ OK ] ボタンをクリックする。
パスワードで保護する場合は、キーペアではなく電子証明書 (内部にキーペアが含まれている。拡張子はpfx) が作成される。パスワードで保護しない場合は、キーペアが作成される。
電子証明書のパスワードは比較的容易に解読可能であるため、パスワードの有無は実質的に、キーペアファイルと電子証明書のどちらを作成するかの違いでしかないと言える。
また、電子証明書は、発行者と発行先が同一な、いわゆるオレオレ証明書なので、電子証明書を作成する必要はあまりないと思われる。 (電子証明書を使う必要がないのではなく、オレオレ証明書を使う必要がないという意味なので注意。)
なお、既存のキーペアや既存の電子証明書を利用する場合は、手順4,5,6の代わりに、コンボボックスの [ <参照...> ] を選択し、参照ダイアログにてファイルを選択する。
[ 参考 ]
アセンブリおよびマニフェストへの署名の管理
@IT:インサイド .NET Framework [改訂版]第2回 アセンブリのアイデンティティ
[ 関連 ]
ClickOnce マニフェストの署名