C# AESを用いた復号化


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

## ■コード

```c#:Crypto.cs
        //================================
        // 復号化する関数：DecryptAes
        // 引数：plain_Text：引数は暗号化されたテキスト(Base64)
        //　　　 key：暗号化key
        //　　　 iv：初期化ベクトル
        //================================
        static public string DecryptAes(string base64_text, byte[] key, byte[] iv)
        {
            string plain_Text;

            // Base64文字列をバイト型配列に変換
            byte[] byte_arr = Convert.FromBase64String(base64_text);

            // AESオブジェクトを作成
            using (Aes aes = Aes.Create())
            {
                // 復号器を作成
                using (ICryptoTransform decryptor = aes.CreateDecryptor(key, iv))
                {
                    // 入力ストリームを作成
                    using (MemoryStream in_stm = new MemoryStream(byte_arr))
                    {
                        // 復号化ストリーム
                        using (CryptoStream crypto_stm = new CryptoStream(in_stm, decryptor, CryptoStreamMode.Read))
                        {
                            //復号化を行い、バイト列→文字列に変換
                            using (StreamReader stm_read = new StreamReader(crypto_stm))
                            {
                                plain_Text = stm_read.ReadToEnd();
                            }
                        }
                    }
                }
            }

            return plain_Text;
        }
```


## ■詳細
### 引数
`base64_text`: 暗号化されたテキスト。
`key`: 暗号化キー。
`iv`: 初期化ベクトル。

### 処理の流れ
**1\. Base64文字列をバイト型配列に変換**
```c#:Crypto.cs
 byte[] byte_arr = Convert.FromBase64String(base64_text);
```
暗号化された文字列(`base64_text`)はBase64形式のため、直接復号することはできない。
Base64形式の文字列をもとのバイト列(バイナリデータ)に変換を行う。


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


**3\.`aes.CreateDecryptor(key, iv)`を使ってデータを復号化するための「復号器」を作成**
```c#:Crypto.cs
ICryptoTransform decryptor = aes.CreateDecryptor(key, iv)
 ```
`key`：暗号化キー
`iv`：初期化ベクトル
暗号化されたバイナリデータをAESの逆操作を用いて復号する。


**4\. メモリストリームを生成**
```c#:Crypto.cs
MemoryStream in_stm = new MemoryStream(byte_arr)
 ```
 `byte_arr`:：暗号化されたバイナリデータ

暗号化されたバイナリデータ( `byte_arr`)を入力ストリームとして扱う。
入力元(読み取り元) = 復号化処理のデータ元として使用される。

 
**5\. メモリストリーム (`out_stm`) に暗号化結果を書き込むための `crypto_stm` を生成**
```c#:Crypto.cs
CryptoStream crypto_stm = new CryptoStream(in_stm, decryptor, CryptoStreamMode.Read)
 ```
`in_stm`：入力元(読み取り元)。暗号化されたデータを格納するメモリストリーム。
`encryptor`：復号化変換器(復号化ロジックを持つ)
`CryptoStreamMode.Read`：読み出しモード。

 入力データを読み出し、復号化を行う。
 
MemoryStream = データを一時的にメモリ上に保存しそれに対し読み書き出来る。ノートみたいなモノ。
CryptoStream = データを「暗号化(復号化)」するためのストリーム。このストリームを通じてデータを読み書きすると自動的に暗号化や複合化が行われる。


**6\. StreamReaderを使用して復号化データを文字列として取得**
```c#:Crypto.cs
using (StreamReader stm_read = new StreamReader(crypto_stm))
{
    plain_Text = stm_read.ReadToEnd();
}
 ```
 `crypto_stm`：復号化後(暗号文が元のバイト列に戻った状態)のデータが含まれるストリーム
 
 復号化されたデータを読み取り、元の平文(文字列)として取得する。

 ～流れは以下～
 ①StreamReaderが復号化されたデータ(`crypto_stm`)から順次データを読み出して `stm_read `に格納
 ②ReadToEndで復号化データ全体をバイトデータ→**文字列**(plain_Text)として取得。
 
StreamReaderはバイトデータを文字データに変換して読み取るクラス



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

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