# 機能設計書 70-CryptoStream

## 概要

本ドキュメントは、VBCorLibライブラリにおけるCryptoStreamクラスの機能設計を記述する。CryptoStreamは、ストリームベースの暗号化・復号化機能を提供し、ICryptoTransformインターフェースを実装したトランスフォームオブジェクトと連携して、データの暗号化または復号化を行う。

### 本機能の処理概要

CryptoStreamクラスは、既存のStreamオブジェクトをラップし、読み取りまたは書き込み時に自動的に暗号化または復号化を行うストリームを提供する。デイジーチェーン（連鎖接続）パターンをサポートし、複数のCryptoStreamを連結して複合的な変換を実現できる。

**業務上の目的・背景**：ファイルやネットワークストリームのデータを暗号化・復号化する際に、ストリーム指向のAPIを提供することで、大量のデータをメモリに一度に読み込むことなく効率的に処理できる。

**機能の利用シーン**：
- ファイルの暗号化・復号化
- ネットワークデータの暗号化送信
- 暗号化アーカイブの作成・展開
- ハッシュ計算のストリーム処理
- 複数段階の暗号変換（圧縮後に暗号化など）

**主要な処理内容**：
1. 基底Streamとトランスフォームの設定
2. 読み取り時の復号化処理（ReadMode）
3. 書き込み時の暗号化処理（WriteMode）
4. ブロック単位でのデータ変換
5. 最終ブロックの処理（FlushFinalBlock）

**関連システム・外部連携**：
- Stream: 基底ストリームインターフェース
- ICryptoTransform: 暗号変換インターフェース
- 各種暗号化クラス（AES, TripleDES, RijndaelManaged等）

**権限による制御**：基底ストリームの権限に依存。

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| - | - | - | 画面機能マッピングに記載なし |

## 機能種別

ストリーム処理 / 暗号化処理 / データ変換

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| Stream | Stream | Yes | 基底ストリーム | Nullでないこと、Modeに応じた読み書き可能性 |
| Transform | ICryptoTransform | Yes | 暗号変換オブジェクト | Nullでないこと |
| Mode | CryptoStreamMode | Yes | 読み取り(ReadMode)または書き込み(WriteMode) | 有効な列挙値 |
| Buffer | Byte() | Yes | ReadBlock/WriteBlockの対象配列 | 有効な配列、範囲チェック |
| Offset | Long | Yes | バッファの開始位置 | 0以上、配列範囲内 |
| Count | Long | Yes | 処理するバイト数 | 0以上、配列範囲内 |

### 入力データソース

- 基底Streamから読み取られるデータ（ReadMode）
- アプリケーションから書き込まれるデータ（WriteMode）

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| ReadBlock戻り値 | Long | 読み取ったバイト数 |
| ReadByte戻り値 | Long | 読み取ったバイト（-1でEOF） |
| Buffer（参照渡し） | Byte() | 変換されたデータ |

### 出力先

- ReadModeでは、変換されたデータがバッファに格納
- WriteModeでは、変換されたデータが基底ストリームに書き込み

## 処理フロー

### 処理シーケンス

```
【ReadMode（復号化）】
1. インスタンス初期化（Init）
   └─ 基底StreamがCanReadであることを確認
   └─ 入力バッファと出力バッファを初期化

2. データ読み取り（ReadBlock）
   └─ 残りバッファがあれば先にコピー
   └─ CanTransformMultipleBlocksならマルチブロック読み取り
   └─ FillBufferで基底Streamから1ブロック読み込み
   └─ Transform.TransformBlockで変換
   └─ 必要量取得まで繰り返し

3. 終了処理（FillBuffer - 最終ブロック）
   └─ Transform.TransformFinalBlockで最終変換

【WriteMode（暗号化）】
1. インスタンス初期化（Init）
   └─ 基底StreamがCanWriteであることを確認
   └─ 入力バッファと出力バッファを初期化

2. データ書き込み（WriteBlock）
   └─ CanTransformMultipleBlocksならマルチブロック書き込み
   └─ WriteToBufferで内部バッファに蓄積
   └─ 1ブロック分たまったらFlushBuffer
   └─ Transform.TransformBlockで変換
   └─ 基底Streamに書き込み

3. 終了処理（FlushFinalBlock）
   └─ Transform.TransformFinalBlockで最終変換
   └─ 結果を基底Streamに書き込み
   └─ 基底がCryptoStreamなら再帰的にFlushFinalBlock
```

### フローチャート

```mermaid
flowchart TD
    subgraph WriteMode
        W1[WriteBlock] --> W2{バッファに蓄積}
        W2 --> W3{1ブロック分?}
        W3 -->|Yes| W4[FlushBuffer]
        W4 --> W5[TransformBlock]
        W5 --> W6[基底Streamに書き込み]
        W3 -->|No| W7[継続]
        W6 --> W7
        W7 --> W8[FlushFinalBlock]
        W8 --> W9[TransformFinalBlock]
        W9 --> W10[最終データ書き込み]
    end

    subgraph ReadMode
        R1[ReadBlock] --> R2{バッファ残りあり?}
        R2 -->|Yes| R3[バッファからコピー]
        R2 -->|No| R4[FillBuffer]
        R4 --> R5[基底Streamから読み込み]
        R5 --> R6{全データ読めた?}
        R6 -->|Yes| R7[TransformBlock]
        R6 -->|No| R8[TransformFinalBlock]
        R7 --> R9[出力バッファに格納]
        R8 --> R9
        R9 --> R3
    end
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-70-01 | モード排他 | ReadModeとWriteModeは同時に使用不可 | 常時 |
| BR-70-02 | 読み取り制限 | ReadModeでは基底StreamがCanRead=True必須 | 初期化時 |
| BR-70-03 | 書き込み制限 | WriteModeでは基底StreamがCanWrite=True必須 | 初期化時 |
| BR-70-04 | FinalBlock一回のみ | FlushFinalBlockは一度しか呼べない | FlushFinalBlock呼び出し時 |
| BR-70-05 | シーク不可 | CanSeekは常にFalse | 常時 |
| BR-70-06 | 自動CloseでFlush | WriteMode時、CloseStreamでFlushFinalBlockを自動呼び出し | CloseStream時 |

### 計算ロジック

**ブロック処理の基本**:
```
InputBlockSize: トランスフォームの入力ブロックサイズ
OutputBlockSize: トランスフォームの出力ブロックサイズ

ReadMode:
  1. 基底Streamから InputBlockSize バイト読み込み
  2. TransformBlock で変換
  3. OutputBlockSize バイトの出力を取得

WriteMode:
  1. アプリケーションから書き込まれたデータを InputBlockSize まで蓄積
  2. TransformBlock で変換
  3. 基底Stream に OutputBlockSize バイト書き込み
```

## データベース操作仕様

本機能はデータベース操作を行わない。

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| ArgumentNullException | 引数Null例外 | StreamまたはTransformがNull | 有効なオブジェクトを渡す |
| ArgumentException | 引数例外 | ReadModeで基底StreamがCanRead=False | 読み取り可能なStreamを渡す |
| ArgumentException | 引数例外 | WriteModeで基底StreamがCanWrite=False | 書き込み可能なStreamを渡す |
| ArgumentOutOfRangeException | 引数範囲外例外 | ModeがReadMode/WriteMode以外 | 有効なCryptoStreamModeを指定 |
| NotSupportedException | 未サポート例外 | Position/Length/SeekPositionにアクセス | シーク不可のため使用不可 |
| NotSupportedException | 未サポート例外 | ReadModeでWriteBlock | モード不一致 |
| NotSupportedException | 未サポート例外 | WriteModeでReadBlock | モード不一致 |
| NotSupportedException | 未サポート例外 | FlushFinalBlock2回目呼び出し | 一度しか呼べない |

### リトライ仕様

エラー発生時のリトライは行わない。

## トランザクション仕様

本機能はトランザクション管理を行わない。

## パフォーマンス要件

- CanTransformMultipleBlocks=Trueのトランスフォームでは複数ブロック一括処理
- ストリーミング処理のため、メモリ使用量は一定
- 内部バッファサイズはブロックサイズに依存
- 大量データでもメモリ効率良く処理可能

## セキュリティ考慮事項

- トランスフォームの種類により暗号強度が決まる
- CloseStream時に自動でFlushFinalBlockが呼ばれる（暗号化完了保証）
- 使用後はCloseStreamを必ず呼び出す
- 基底ストリームのセキュリティ設定に注意

## 備考

- .NET FrameworkのSystem.Security.Cryptography.CryptoStreamクラスと互換性のあるAPI設計
- Streamインターフェースを実装し、標準的なストリーム操作が可能
- デイジーチェーンパターンで複数のCryptoStreamを連結可能
- 非同期操作（BeginRead/BeginWrite）もサポート（内部は同期処理）

---

## コードリーディングガイド

本機能を理解するために参照すべきファイルと、推奨する読み解き順序を以下に示す。

### 推奨読解順序

#### Step 1: クラスの全体構造を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | CryptoStream.cls | `Source/CorLib/System.Security.Cryptography/CryptoStream.cls` | メインクラスの構造 |

**主要メンバ変数**:
- **63-73行目**: mMode, mStream, mTransform, mInputBuffer, mOutputBuffer, mInputIndex, mOutputIndex, mBytesBuffered, mFinalTransformed, mOutputBlockSize, mInputBlockSize

**CryptoStreamMode列挙型**:
- **58-61行目**: ReadMode = 0, WriteMode = 1

#### Step 2: 初期化処理を理解する

**Init（648-674行目）の詳細**:
1. **649-652行目**: NullチェックとArgumentNullException
2. **654-665行目**: Modeに応じた基底Stream能力チェック
3. **667-668行目**: mStream, mTransformの設定
4. **671-673行目**: ブロックサイズ取得とバッファ初期化

#### Step 3: 読み取り処理を理解する

**ReadBlock（329-354行目）の詳細**:
1. **330-331行目**: CanReadチェック
2. **337行目**: バッファ残りから読み取り
3. **340-341行目**: マルチブロック読み取り（可能な場合）
4. **345-350行目**: FillBufferで基底から取得しながらループ

**FillBuffer（693-715行目）の詳細**:
1. **698行目**: 基底Streamから1ブロック読み込み
2. **701-703行目**: フルブロック読めたらTransformBlock
3. **708-710行目**: 読めなかったらTransformFinalBlock

#### Step 4: 書き込み処理を理解する

**WriteBlock（482-495行目）の詳細**:
1. **483-484行目**: CanWriteチェック
2. **488-490行目**: マルチブロック書き込み（可能な場合）
3. **492-494行目**: WriteToBufferでバッファに蓄積

**FlushFinalBlock（279-297行目）の詳細**:
1. **280-283行目**: CanWrite/二重呼び出しチェック
2. **285-286行目**: TransformFinalBlockで最終変換
3. **288-292行目**: 基底がCryptoStreamなら再帰呼び出し

### プログラム呼び出し階層図

```
CryptoStream
    │
    ├─ Init(Stream, Transform, Mode)
    │      ├─ CanRead/CanWrite チェック
    │      └─ InitBuffers()
    │
    ├─ ReadBlock(Buffer, Offset, Count)  [ReadMode]
    │      ├─ ReadBufferedBytes()
    │      ├─ ReadMultiBlock() [CanTransformMultipleBlocks]
    │      └─ FillBuffer()
    │             ├─ mStream.ReadBlock()
    │             ├─ mTransform.TransformBlock()
    │             └─ mTransform.TransformFinalBlock()
    │
    ├─ WriteBlock(Buffer, Offset, Count)  [WriteMode]
    │      ├─ WriteMultiBlock() [CanTransformMultipleBlocks]
    │      └─ WriteToBuffer()
    │             └─ FlushBuffer()
    │                    ├─ mTransform.TransformBlock()
    │                    └─ mStream.WriteBlock()
    │
    ├─ FlushFinalBlock()  [WriteMode]
    │      ├─ mTransform.TransformFinalBlock()
    │      ├─ mStream.WriteBlock()
    │      └─ CryptoStream.FlushFinalBlock() [基底がCSの場合]
    │
    └─ CloseStream()
           ├─ FlushFinalBlock() [WriteMode]
           └─ mStream.CloseStream()
```

### データフロー図

```
【WriteMode（暗号化）】

[アプリケーション]              [CryptoStream]                [基底Stream]

WriteBlock(Data) ────────▶ ┌─────────────┐
                          │ InputBuffer │
                          │  (蓄積)     │
                          └─────────────┘
                                │
                          ┌─────▼─────┐
                          │TransformBlk│
                          └─────┬─────┘
                                │
                          ┌─────▼─────┐
                          │OutputBuffer│ ────────▶ WriteBlock
                          └───────────┘

【ReadMode（復号化）】

[基底Stream]                [CryptoStream]              [アプリケーション]

ReadBlock ────────────▶ ┌─────────────┐
                        │ InputBuffer │
                        └─────────────┘
                              │
                        ┌─────▼─────┐
                        │TransformBlk│
                        └─────┬─────┘
                              │
                        ┌─────▼─────┐
                        │OutputBuffer│ ────────▶ ReadBlock(Buffer)
                        └───────────┘
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| CryptoStream.cls | `Source/CorLib/System.Security.Cryptography/CryptoStream.cls` | ソース | メインクラス |
| Stream.cls | `Source/CorLib/System.IO/Stream.cls` | ソース | 基底インターフェース |
| ICryptoTransform.cls | `Source/CorLib/System.Security.Cryptography/ICryptoTransform.cls` | ソース | 変換インターフェース |
| StreamAsyncResult.cls | `Source/CorLib/System.IO/StreamAsyncResult.cls` | ソース | 非同期結果 |
