# 機能設計書 68-RNGCryptoServiceProvider

## 概要

本ドキュメントは、VBCorLibライブラリにおけるRNGCryptoServiceProviderクラスの機能設計を記述する。RNGCryptoServiceProviderは、Windows暗号化サービスプロバイダー（CSP）を使用した暗号論的に安全な乱数生成機能を提供するクラスである。

### 本機能の処理概要

RNGCryptoServiceProviderクラスは、暗号論的に安全な擬似乱数（CSPRNG: Cryptographically Secure Pseudo-Random Number Generator）を生成する機能を提供する。Windows CryptoAPIのCryptGenRandom関数を使用し、予測不可能な高品質の乱数バイト列を生成する。

**業務上の目的・背景**：暗号鍵の生成、ソルト値の生成、ナンス（nonce）の生成など、セキュリティに関わる乱数が必要な場面では、通常のRnd関数では不十分であり、暗号論的に安全な乱数生成器が必要となる。

**機能の利用シーン**：
- 対称暗号鍵の生成
- ソルト値の生成（パスワードハッシュ用）
- IV（初期化ベクトル）の生成
- セッションIDの生成
- トークン生成
- HMAC用秘密鍵の自動生成（HMACBase内部）

**主要な処理内容**：
1. 暗号化サービスプロバイダー（CSP）コンテキストの取得
2. 指定されたバイト配列を乱数で充填（GetBytes）
3. ゼロを含まない乱数バイト列の生成（GetNonZeroBytes）
4. リソースの解放（Class_Terminate）

**関連システム・外部連携**：
- Windows CryptoAPI: CryptAcquireContext, CryptGenRandom関数
- CspParameters: プロバイダー設定の指定
- CryptoAPI（内部モジュール）: コンテキスト管理

**権限による制御**：Windowsの暗号化サービスプロバイダー（CSP）へのアクセスが必要。

## 関連画面

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

## 機能種別

計算処理 / 乱数生成 / セキュリティ

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| Data | Byte() | Yes | 乱数を格納するバイト配列 | Nullでないこと |
| CspParams | CspParameters | No | CSPの設定パラメータ | Nullでないこと（Initメソッド用） |

### 入力データソース

- アプリケーションから提供される空のバイト配列（乱数格納先）
- CspParametersオブジェクト（オプション）

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| Data（参照渡し） | Byte() | 乱数で充填されたバイト配列 |

### 出力先

- 参照渡しで渡されたバイト配列が乱数で充填される

## 処理フロー

### 処理シーケンス

```
1. インスタンス使用開始
   └─ 初回のGetBytes呼び出しまでCSPコンテキストは取得しない（遅延初期化）

2. プロバイダー検証（VerifyProvider）
   └─ mProviderがvbNullPtrの場合
   └─ CspParameters(PROV_RSA_AES)で初期化
   └─ CryptoAPI.AcquireContextでCSPコンテキスト取得

3. 乱数生成（GetBytes）
   └─ VerifyProviderでコンテキスト確保
   └─ CryptGenRandom API呼び出し
   └─ 配列全体を乱数で充填

4. 非ゼロ乱数生成（GetNonZeroBytes）
   └─ 要求サイズの2倍の配列を用意
   └─ GetBytesで乱数充填
   └─ ゼロ以外のバイトのみを結果配列にコピー

5. リソース解放（Class_Terminate）
   └─ CryptoAPI.ReleaseContextでコンテキスト解放
```

### フローチャート

```mermaid
flowchart TD
    A[GetBytes呼び出し] --> B{mProvider == 0?}
    B -->|Yes| C[VerifyProvider]
    C --> D[CspParameters作成]
    D --> E[AcquireContext]
    E --> F[CSPコンテキスト取得]
    B -->|No| F
    F --> G[CryptGenRandom呼び出し]
    G --> H{成功?}
    H -->|Yes| I[配列に乱数格納]
    H -->|No| J[CryptographicException]
    I --> K[終了]
    J --> K
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-68-01 | 遅延初期化 | CSPコンテキストは初回GetBytes呼び出しまで取得しない | GetBytes/GetNonZeroBytes呼び出し時 |
| BR-68-02 | デフォルトプロバイダー | 未指定時はPROV_RSA_AESを使用 | CspParametersなしでInit呼び出し時 |
| BR-68-03 | コンテキスト解放 | Class_Terminate時に必ずReleaseContext | インスタンス破棄時 |
| BR-68-04 | 非ゼロ生成戦略 | 2倍サイズの配列を生成してゼロをフィルター | GetNonZeroBytes呼び出し時 |

### 計算ロジック

**GetNonZeroBytesのアルゴリズム**:
```
1. 要求サイズ n に対して、2n バイトの配列を生成
2. GetBytes で 2n バイトの乱数を取得
3. ゼロ以外のバイトを順次結果配列にコピー
4. 必要数に達したら終了
   （確率的にゼロが50%以下のため、2倍あればほぼ確実に足りる）
```

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

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

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| ArgumentNullException | 引数Null例外 | Data配列がNullの場合 | 有効なByte配列を渡す |
| ArgumentNullException | 引数Null例外 | Init時にCspParamsがNullの場合 | 有効なCspParametersを渡す |
| CryptographicException | 暗号例外 | CryptGenRandomが失敗した場合 | システムのCSP状態を確認 |

### リトライ仕様

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

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

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

## パフォーマンス要件

- CSPコンテキストの取得は比較的重い操作のため、遅延初期化を採用
- 一度取得したコンテキストはインスタンスの寿命中再利用
- 大量の乱数が必要な場合は、一度に大きな配列を取得することを推奨
- GetNonZeroBytesは2倍のサイズを生成するため、通常のGetBytesより遅い

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

- 暗号論的に安全な乱数を提供（CSPRNG）
- VB6のRnd関数よりも格段に高品質な乱数
- 生成された乱数をログに出力しない
- 鍵として使用する場合は適切な鍵長を確保
- 使用後の配列は必要に応じてゼロクリア

## 備考

- .NET FrameworkのSystem.Security.Cryptography.RNGCryptoServiceProviderクラスと互換性のあるAPI設計
- Windows CryptoAPI（CryptGenRandom）に依存
- RandomNumberGeneratorインターフェースを実装
- HMACBaseなど他の暗号クラスから内部的に使用される

---

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

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

### 推奨読解順序

#### Step 1: インターフェースを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | RandomNumberGenerator.cls | `Source/CorLib/System.Security.Cryptography/RandomNumberGenerator.cls` | 乱数生成インターフェース |

#### Step 2: メインクラスの構造を理解する

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

**主要処理フロー**:
1. **46行目**: mProvider - CSPコンテキストハンドル
2. **54-62行目**: GetBytes - 乱数生成の主要メソッド
3. **69-94行目**: GetNonZeroBytes - ゼロ除外乱数生成
4. **154-158行目**: VerifyProvider - 遅延初期化
5. **135-142行目**: Init - CspParametersでの初期化
6. **144-148行目**: Class_Terminate - コンテキスト解放

#### Step 3: CryptoAPI呼び出しを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | CryptoAPI.cls | `Source/CorLib/System.Security.Cryptography/CryptoAPI.cls` | Windows API呼び出し |

**読解のコツ**: RNGCryptoServiceProviderは、CryptoAPI.AcquireContextでCSPコンテキストを取得し、直接CryptGenRandom API（60行目）を呼び出して乱数を生成する。

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

```
RNGCryptoServiceProvider
    │
    ├─ GetBytes(Data)
    │      ├─ VerifyProvider()
    │      │      └─ CryptoAPI.AcquireContext() [初回のみ]
    │      └─ CryptGenRandom(mProvider, Length, Data)
    │
    ├─ GetNonZeroBytes(Data)
    │      ├─ GetBytes(BigData)  [2倍サイズ]
    │      └─ ゼロフィルタリング
    │
    ├─ Init(CspParams)
    │      └─ CryptoAPI.AcquireContext()
    │
    └─ Class_Terminate()
           └─ CryptoAPI.ReleaseContext()
```

### データフロー図

```
[入力]                      [処理]                           [出力]

空のByte配列 ──────────────┐
(Data)                    ▼
                    ┌─────────────┐
                    │VerifyProvider│
                    │ CSPコンテキスト│
                    │   取得      │
                    └─────────────┘
                          │
                          ▼
                    ┌─────────────┐
                    │CryptGenRandom│ ──────▶ 乱数で充填された
                    │  API呼び出し │         Byte配列
                    └─────────────┘
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| RNGCryptoServiceProvider.cls | `Source/CorLib/System.Security.Cryptography/RNGCryptoServiceProvider.cls` | ソース | メインクラス |
| RandomNumberGenerator.cls | `Source/CorLib/System.Security.Cryptography/RandomNumberGenerator.cls` | ソース | インターフェース |
| CryptoAPI.cls | `Source/CorLib/System.Security.Cryptography/CryptoAPI.cls` | ソース | Windows API呼び出し |
| CspParameters.cls | `Source/CorLib/System.Security.Cryptography/CspParameters.cls` | ソース | CSP設定パラメータ |
| CryptoHelper.cls | `Source/CorLib/System.Security.Cryptography/CryptoHelper.cls` | ソース | 暗号処理ヘルパー（内部で使用） |
