C# AESを用いた暗号化

## ■概要
C#でのAESを用いた暗号化を行う。
何をやっているのかしっくりこなかったため、処理を噛み砕いて記載してみた。

## ■コード
暗号化: 平文の文字列をAESを用いて暗号化し、Base64形式で出力。
```c#:Crypto.c
using System;
using System.Collections.Generic;
using System.Linq;
using System.Security.Cryptography;
using System.Text;
using System.Threading.Tasks;

namespace PWKeeper
{
    internal class Crypto
    {
        //================================
        // 暗号化する関数：EncryptAes
        // 引数：plain_Text：平文
        //　　　 key：暗号化key
        //　　　 iv：初期化ベクトル
        //================================
        static public string EncryptAes(string plain_Text, byte[] key, byte[] iv) 
        {
            // 暗号化した文字列格納用
            string encrypted_Text;

            // Aesオブジェクトを作成
            using (Aes aes = Aes.Create())
            {
                // 変換器の作成
                using (ICryptoTransform encryptor = aes.CreateEncryptor(key, iv))
                {
                    // 出力先ストリームを作成
                    using (MemoryStream out_stm = new MemoryStream())
                    {
                        // 暗号化用ストリームを作成
                        using (CryptoStream crypto_stm  = new CryptoStream(out_stm, encryptor, CryptoStreamMode.Write))
                        {
                            //ストリームに書き込むための処理
                            using (StreamWriter stm_write = new StreamWriter(crypto_stm))
                            {
                                //平文を暗号化
                                stm_write.Write(plain_Text);
                            }
                        }
                        // Base64文字列に変換
                        byte[] result = out_stm.ToArray();
                        encrypted_Text = Convert.ToBase64String(result);
                    }
                }
            }
            return encrypted_Text;
        }
    }
}
```

## ■詳細
### 引数
`plain_text`: 暗号化する平文。
`key`: 暗号化キー。
`iv`: 初期化ベクトル。

### 処理の流れ
**1\. `Aes.Create()` でAES暗号化オブジェクトを生成**
```c#:Crypto.cs
Aes aes = Aes.Create()
```

**2\. `aes.CreateEncryptor(key, iv)` を使ってデータを暗号化するための「変換器」を作成**
```c#:Crypto.cs
ICryptoTransform encryptor = aes.CreateEncryptor(key, iv)
```
`key`： 暗号化キー
`iv`： 初期化ベクトル

**3\. メモリストリームを生成**
```c#:Crypto.cs
MemoryStream out_stm = new MemoryStream()
 ```
暗号化されたデータの出力先として使用するメモリストリームを生成。
 
**4\. メモリストリーム (`out_stm`) に暗号化結果を書き込むための `crypto_stm` を生成**
```c#:Crypto.cs
CryptoStream cs = new CryptoStream(out_stream, encryptor, CryptoStreamMode.Write)
 ```
`out_stream`：出力先。暗号化されたデータを格納するメモリストリーム。
`encryptor`：暗号化変換器(暗号化ロジックを持つ)
`CryptoStreamMode.Write`：書き込みモード。
 
MemoryStream = データを一時的にメモリ上に保存しそれに対し読み書き出来る。ノートみたいなモノ。
CryptoStream = データを「暗号化(復号化)」するためのストリーム。このストリームを通じてデータを読み書きすると自動的に暗号化や複合化が行われる。

**5\. ストリームに書き込むためにStreamWriterを生成**
```c#:Crypto.cs
StreamWriter sw = new StreamWriter(crypto_stm)
 ```
 `crypto_stm`：データを書き込む出力先
 StreamWriterは文字データをストリームに書き込むためのクラス
 (内部で文字列をバイナリ形式に変換してストリームに渡す)

**6\. 平文を書き込み**
```c#:Crypto.cs
stm_write.Write(plain_Text);
 ```
`plain_Text`：平文

～流れは以下～
①平文データ（plain_Text）を StreamWriter に渡す。
②Writeメソッドでそのデータを CryptoStream に出力。
③CryptoStream はデータをリアルタイムで暗号化。
④暗号化後のデータが out_stream に保存される。


**7\. 暗号化結果をBase64形式に変換**
```c#:Crypto.cs
 byte[] result = out_stm.ToArray();
 encrypted_Text = Convert.ToBase64String(result);
 ```
 暗号化されたデータは通常「バイナリ形式」。
 Base64に変換することで、暗号化データを文字列として扱えるようになる。
 ※バイナリ形式は、ファイルやプロトコルで問題を起こす可能性がある

## ■参考文献
https://ito-room.com/aes-string-csharp/

https://learn.microsoft.com/ja-jp/dotnet/api/system.security.cryptography.aes?view=net-8.0