C#でファイルのAES暗号化


## ファイル暗号化クラス

ファイルの暗号化、復号化を行うためのクラス。

引数には、それぞれ入力ファイルストリーム、出力ファイルストリーム、パスワードを入力。

```c#:FileEncryptor
using System;
using System.Security.Cryptography;
using System.Text;
using System.IO;

namespace EncryptTest
{
	/// <summary>
	/// File Encryptor Class
	/// </summary>
	public static class FileEncryptor
	{
		/// <summary>
		/// Key Length
		/// </summary>
		public const int KeyLength = 16;

		/// <summary>
		/// Generate Byte Key from Password
		/// </summary>
		/// <returns>Byte Key</returns>
		/// <param name="password">Password</param>
		private static byte[] GenerateByteKey(string password)
		{
			/* Get Bytes of Password */
			var bytesPassword = Encoding.UTF8.GetBytes(password);
			/* Create Bytes Key Array */
			var bytesKey = new byte[KeyLength];

			/* Loop to Key Length */
			for(int i = 0; i < KeyLength; i++)
			{
				/* Copy Password Byte Array and fill remain bytes by 0 */
				bytesKey[i] = (i < bytesPassword.Length) ? bytesPassword[i] : (byte)0;
			}

			return bytesKey;
		}

		/// <summary>
		/// Encrypt File
		/// </summary>
		/// <param name="ifs">Input File Stream</param>
		/// <param name="ofs">Output File Stream</param>
		/// <param name="password">Password</param>
		public static void Encrypt(Stream ifs, Stream ofs, string password)
		{
			/* Generate Byte Key from Password */
			var bytesKey = FileEncryptor.GenerateByteKey(password);

			/* Create AES Crypto Service Provider */
			var aes = new AesCryptoServiceProvider() {
				BlockSize = 128,
				KeySize = 128,
				Mode = CipherMode.CBC,
				Padding = PaddingMode.PKCS7,
				Key = bytesKey,
			};

			/* Generate Random Initialization Vector(IV) */
			aes.GenerateIV();

			/* Get IV */
			var bytesIV = aes.IV;

			/* Write IV to File (128bit=16bytes) */
			ofs.Write(bytesIV, 0, 16);

			/* Create AES Encryptor */
			using(var encrypt = aes.CreateEncryptor())
			{
				/* Create Crypto Stream */
				using(var cs = new CryptoStream(ofs, encrypt, CryptoStreamMode.Write))
				{
					/* Inifity Loop */
					while(true)
					{
						/* Create Write Buffer */
						var buffer = new byte[1024];
						/* Read File to Buffer */
						var len = ifs.Read(buffer, 0, buffer.Length);

						/* Read Data Size is larger than 0 */
						if(len > 0)
						{
							/* Write Read Data to Crypto Stream */
							cs.Write(buffer, 0, len);
						}
						else
						{
							/* End of Input File */
							break;
						}
					}
				}
			}
		}

		/// <summary>
		/// Decrypt File
		/// </summary>
		/// <param name="ifs">Input File Stream</param>
		/// <param name="ofs">Output File Stream</param>
		/// <param name="password">Password</param>
		public static void Decrypt(Stream ifs, Stream ofs, string password)
		{
			/* Generate Byte Key from Password */
			var bytesKey = FileEncryptor.GenerateByteKey(password);

			/* Create AES Crypto Service Provider */
			var aes = new AesCryptoServiceProvider() {
				BlockSize = 128,
				KeySize = 128,
				Mode = CipherMode.CBC,
				Padding = PaddingMode.PKCS7,
				Key = bytesKey,
			};
				
			/* Create IV Buffer */
			var bytesIV = new byte[KeyLength];

			/* Read IV from Input File */
			ifs.Read(bytesIV, 0, KeyLength);

			/* Set Read IV */
			aes.IV = bytesIV;

			/* Create AES Decryptor */
			using(var encrypt = aes.CreateDecryptor())
			{
				/* Create Crypto Stream */
				using(var cs = new CryptoStream(ofs, encrypt, CryptoStreamMode.Write))
				{
					/* Inifinity Loop */
					while(true)
					{
						/* Create Read Buffer */
						var buffer = new byte[1024];

						/* Read Input File to Buffer */
						var len = ifs.Read(buffer, 0, buffer.Length);

						/* Read Data Size is larger than 0 */
						if(len > 0)
						{
							/* Write Read Data to Crypto Stream */
							cs.Write(buffer, 0, len);
						}
						else
						{
							/* End of Data */
							break;
						}
					}
				}
			}
		}
	}
}
```

## Usage

使い方は、
1. 入力ファイル(平文)、出力ファイル(暗号化ファイル)のストリームを生成し、暗号化用パスワードを入力してファイルを暗号化
2. 入力ファイル(暗号化ファイル)、出力ファイル(復号化ファイル)のストリームを生成し、暗号化に使用したパスワードを入力してファイルを復号化

```c#:Program.cs
class MainClass
{
	public static void Main(string[] args)
	{	
		/* Create Input File Stream */
		using(var eifs = new FileStream("InputFile.txt", FileMode.Open, FileAccess.Read))
        {
            /* Create Output File Stream*/
            using(var eofs = new FileStream("EncryptedFile.bin", FileMode.Create, FileAccess.Write))
            {
                /* Encrypt File */
                FileEncryptor.Encrypt(eifs, eofs, "Password");
            }
        }
		
		/* Create Input File Stream */
		using(var difs = new FileStream("EncryptedFile.bin", FileMode.Open, FileAccess.Read))
        {
            /* Create Output File Stream*/
            using(var dofs = new FileStream("DecryptedFile.txt", FileMode.Create, FileAccess.Write))
            {
                /* Decrypt File */
                FileEncryptor.Decrypt(difs, dofs, "Password");
            }
        }
	}
}
```