暗号化をWindowsに任せる

Data Protection API (DPAPI)を使う方法です。
.NET 2.0以前はP/Invokeを用いる必要がありましたが、
2.0以降はクラスが用意されたみたいでございます。


秘密情報の暗号化および鍵の管理をWindowsにお願いします。
ある文書に暗号化を施したけどその秘密鍵をどうやって管理しようかなーという時に。
独自で変な防御策を作るよりはこっちの方が安全。


かなり簡単にこの有難い機能を使うことが出来ます。
ただ、16バイトか、16の倍数バイトである必要があります。

using System.Security.Cryptography; //System.Security.dllの参照の追加が必要
〜〜
public class Test
{
	private readonly Encoding encode = Encoding.Unicode;
	private readonly MemoryProtectionScope scope =
		MemoryProtectionScope.SameProcess & MemoryProtectionScope.SameLogon;
	private byte[] data;

	public void Protect()
	{
		Console.WriteLine( "password :" );
		this.data = this.encode.GetBytes( Console.ReadLine() );
		if ( this.data.Length != 16 ) // @1
			Array.Resize<byte>( ref this.data, (this.data.Length / 16 + 1) * 16 );

		ProtectedMemory.Protect( this.data, this.scope );
		Console.WriteLine( this.encode.GetString( this.data ) );
	}

	public void Unprotect()
	{
		ProtectedMemory.Unprotect( this.data, this.scope );
		string pass = this.encode.GetString( this.data );
		pass = pass.Replace( "\0", "" ); // @2

		Console.WriteLine( pass );
	}
}


@部分について補足を。
@1 :
 ちょうど16バイトの時に32バイトにリサイズされてしまうため、それを回避。(みみっちい
@2 :
 ある倍数(確かめてないので不明)に足りない場合、\0で埋められてるみたいです。
 ので、Replaceにより不要な\0をカット。


MemoryProtectionScope列挙体には3つのメンバが定義されているので、
メモリ保護の解除ができる人(とかプロセス)を制限できます。


あと、ProtectedDataクラスという似たようなクラスもあります。
ProtectedMemoryはメモリ上のデータを暗号化するのが目的で、
暗号化されたものをファイルに保存したい場合はProtectedDataクラスを使います。
ちなみにSecureStringクラスは内部でDPAPIを使っているそうです。



参考:
http://www.microsoft.com/japan/msdn/netframework/skillup/core/article5.aspx
http://www.microsoft.com/japan/msdn/enterprise/pag/securityguidance/PAGGuidelines0003.aspx
http://msdn2.microsoft.com/ja-jp/library/system.security.cryptography.protectedmemory.protect.aspx
http://msdn2.microsoft.com/ja-jp/library/system.security.cryptography.memoryprotectionscope.aspx
http://msdn2.microsoft.com/ja-jp/library/ms229741.aspx