# 機能設計書 605-New-DbaDbAsymmetricKey

## 概要

本ドキュメントは、SQL Serverデータベースに暗号化およびデジタル署名用のRSA非対称キーを作成する`New-DbaDbAsymmetricKey`機能の設計書である。

### 本機能の処理概要

`New-DbaDbAsymmetricKey`は、RSA暗号化アルゴリズム（512〜4096ビット）を使用してSQL Serverデータベース内に非対称キーを作成する機能である。これらのキーは、Transparent Data Encryption（TDE）、列レベル暗号化、アセンブリやストアドプロシージャのデジタル署名などのデータベースレベルの暗号化機能に不可欠である。

**業務上の目的・背景**：企業のセキュリティ要件やコンプライアンス規制（PCI-DSS、HIPAA、GDPR等）では、機密データの暗号化が求められる。非対称キーは公開鍵暗号方式を使用し、キー交換やデジタル署名に適している。本機能は、新しいキーペアをサーバー上で直接生成するか、ファイル、実行ファイル、またはアセンブリから既存のキーをインポートすることができる。

**機能の利用シーン**：
- TDE（透過的データ暗号化）の設定時にデータベース暗号化キーを保護するキーの作成
- 列レベル暗号化の実装
- CLRアセンブリやストアドプロシージャのデジタル署名
- キーの所有者を特定のデータベースユーザーに割り当て

**主要な処理内容**：
1. ターゲットデータベースへの接続（Get-DbaDatabase経由）
2. 既存の非対称キーの存在チェック
3. キーソースの検証（ファイル、実行ファイル、SQLアセンブリの場合）
4. SMO AsymmetricKeyオブジェクトの作成と構成
5. 非対称キーの作成（パスワード保護またはマスターキー保護）

**関連システム・外部連携**：SQL Server SMO、SQL Server暗号化階層

**権限による制御**：データベースへのCREATE ASYMMETRIC KEY権限、およびキー所有者を指定する場合はALTER ANY ASYMMETRIC KEY権限が必要。

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| - | なし | - | CLIベースの機能のため関連画面なし |

## 機能種別

オブジェクト作成（INSERT相当） / 暗号化キー管理

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| SqlInstance | DbaInstanceParameter[] | No | ターゲットSQL Serverインスタンス | なし |
| SqlCredential | PSCredential | No | SQL Server接続用の代替資格情報 | なし |
| Database | String[] | No | 非対称キーを作成するデータベース（デフォルト: master） | なし |
| Name | String[] | No | 非対称キー名（デフォルト: データベース名） | なし |
| SecurePassword | SecureString | No | 秘密鍵を暗号化するパスワード | なし |
| Owner | String | No | 非対称キーの所有者となるデータベースユーザー | なし |
| KeySource | String | No | 外部キーソースのパスまたは名前 | なし |
| KeySourceType | String | No | キーソースの種類 | Executable, File, SqlAssembly |
| InputObject | Database[] | No | Get-DbaDatabase からパイプライン入力 | なし |
| Algorithm | String | No | RSA暗号化アルゴリズム（デフォルト: Rsa2048） | Rsa4096, Rsa3072, Rsa2048, Rsa1024, Rsa512 |
| EnableException | Switch | No | 例外処理の有効化フラグ | なし |

### 入力データソース

- SQL Server SMO
- 外部ファイル（KeySourceType = File の場合）
- 実行ファイル（KeySourceType = Executable の場合）
- SQLアセンブリ（KeySourceType = SqlAssembly の場合）

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| ComputerName | String | SQL Serverインスタンスのコンピュータ名 |
| InstanceName | String | SQL Serverインスタンス名 |
| SqlInstance | String | 完全なSQL Serverインスタンス名（コンピュータ\インスタンス形式） |
| Database | String | 非対称キーが作成されたデータベース名 |
| Name | String | 非対称キーの名前 |
| Owner | String | 非対称キーの所有者 |
| KeyEncryptionAlgorithm | String | 使用されたRSAアルゴリズム |
| KeyLength | Int | キー長（ビット） |
| PrivateKeyEncryptionType | String | 秘密鍵の暗号化タイプ（Password, MasterKey, None） |
| Thumbprint | String | 公開鍵のSHA-1ハッシュ |

### 出力先

PowerShellパイプライン（Microsoft.SqlServer.Management.Smo.AsymmetricKey オブジェクト）

## 処理フロー

### 処理シーケンス

```
1. 前処理（beginブロック）
   └─ KeySourceとKeySourceTypeの両方が指定されているか検証
2. 各InputObject（データベース）に対して処理（processブロック）
   ├─ SqlInstanceが指定された場合はGet-DbaDatabase で取得
   ├─ Name未指定時はデータベース名を使用
   ├─ 既存の非対称キー存在チェック
   ├─ Owner指定時はGet-DbaDbUserで存在確認
   ├─ KeySource指定時はTest-DbaPathで存在確認
   └─ SMO AsymmetricKey.Create() で非対称キーを作成
```

### フローチャート

```mermaid
flowchart TD
    A[開始] --> B{KeySource/KeySourceType検証}
    B -->|片方のみ指定| C[エラー終了]
    B -->|OK| D[データベースループ開始]
    D --> E{Name指定?}
    E -->|No| F[データベース名を使用]
    E -->|Yes| G[指定名を使用]
    F --> H[既存キー存在チェック]
    G --> H
    H -->|存在| I[エラー出力してスキップ]
    H -->|存在しない| J{Owner指定?}
    J -->|Yes| K[ユーザー存在確認]
    K -->|不明/曖昧| L[エラー出力してスキップ]
    K -->|存在| M{KeySource指定?}
    J -->|No| M
    M -->|Yes| N[ソース存在確認 Test-DbaPath]
    N -->|存在しない| O[エラー出力してスキップ]
    N -->|存在| P[AsymmetricKey.Create with KeySource]
    M -->|No| Q[AsymmetricKey.Create with Algorithm]
    P --> R[結果出力]
    Q --> R
    R --> S{次のデータベース?}
    I --> S
    L --> S
    O --> S
    S -->|Yes| D
    S -->|No| T[終了]
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-605-01 | KeySource/KeySourceType同時指定 | KeySourceとKeySourceTypeは両方指定するか両方省略する | 常時 |
| BR-605-02 | デフォルトデータベース | Database未指定時はmasterを使用 | Database未指定時 |
| BR-605-03 | デフォルトキー名 | Name未指定時はデータベース名を使用 | Name未指定時 |
| BR-605-04 | デフォルトアルゴリズム | Algorithm未指定時はRsa2048を使用 | Algorithm未指定時 |
| BR-605-05 | 重複キー禁止 | 同名の非対称キーが既に存在する場合はエラー | 常時 |
| BR-605-06 | 所有者検証 | Owner指定時は対象データベースに存在する一意のユーザーである必要がある | Owner指定時 |
| BR-605-07 | キーソース検証 | KeySource指定時はSQL Serverからアクセス可能なパス/アセンブリである必要がある | KeySource指定時 |

### 計算ロジック

特になし

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

### 操作別データベース影響一覧

| 操作 | 対象テーブル | 操作種別 | 概要 |
|-----|-------------|---------|------|
| 非対称キー作成 | sys.asymmetric_keys | INSERT | 非対称キーレコードの作成 |

### テーブル別操作詳細

#### sys.asymmetric_keys

| 操作 | 項目（カラム名） | 更新値・取得条件 | 備考 |
|-----|-----------------|-----------------|------|
| INSERT | name | 指定されたキー名 | Name パラメータまたはデータベース名 |
| INSERT | algorithm_desc | 指定されたアルゴリズム | RSA_512, RSA_1024, RSA_2048, RSA_3072, RSA_4096 |
| INSERT | key_length | キー長（ビット） | 512, 1024, 2048, 3072, 4096 |
| INSERT | pvt_key_encryption_type | 秘密鍵暗号化タイプ | MK（マスターキー）, PW（パスワード）, NA（暗号化なし） |

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| - | パラメータエラー | KeySourceまたはKeySourceTypeの片方のみ指定 | 両方指定するか両方省略 |
| - | 重複エラー | 同名の非対称キーが既に存在 | 別の名前を使用 |
| - | ユーザー未検出 | 指定されたOwnerがデータベースに存在しない | 正しいユーザー名を指定 |
| - | パス未検出 | KeySourceのパスにSQL Serverからアクセスできない | SQL Serverサービスアカウントからアクセス可能なパスを指定 |
| - | アセンブリ未検出 | 指定されたSQLアセンブリが存在しない | 正しいアセンブリ名を指定 |
| - | 作成失敗 | SMO操作でエラー発生 | エラーメッセージを確認 |

### リトライ仕様

特になし

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

SMOによる非対称キー作成は暗黙のトランザクション内で実行される

## パフォーマンス要件

特に規定なし（キー生成時間はキー長に依存、Rsa4096は数秒かかる場合がある）

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

- CREATE ASYMMETRIC KEY権限が必要
- Owner指定時はALTER ANY ASYMMETRIC KEY権限が必要
- パスワード保護なしの場合、データベースマスターキーで保護される
- 秘密鍵はSQL Server内部で安全に管理される
- SecurePasswordはSecureString型で安全に取り扱われる

## 備考

- Rsa2048がセキュリティと性能のバランスが良く推奨
- TDE用途では通常、masterデータベースに非対称キーを作成する
- KeySourceからインポートする場合、SNKファイル（強力な名前のキーファイル）形式がサポートされる

---

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

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

### 推奨読解順序

#### Step 1: データ構造を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | New-DbaDbAsymmetricKey.ps1 | `public/New-DbaDbAsymmetricKey.ps1` | 73-91行目のコメントで出力オブジェクト（AsymmetricKey）の構造を確認 |
| 1-2 | New-DbaDbAsymmetricKey.ps1 | `public/New-DbaDbAsymmetricKey.ps1` | 107-124行目のparamブロックで入力パラメータ定義を確認 |

**読解のコツ**: SMO AsymmetricKeyオブジェクトをラップしてdbatools固有のプロパティ（ComputerName, SqlInstance等）を追加している点に注目。

#### Step 2: beginブロックのパラメータ検証を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | New-DbaDbAsymmetricKey.ps1 | `public/New-DbaDbAsymmetricKey.ps1` | 125-130行目のbeginブロックでKeySource/KeySourceType検証を確認 |

**主要処理フロー**:
- **126行目**: Test-Bound を使用したXOR条件チェック

#### Step 3: processブロックの主処理を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | New-DbaDbAsymmetricKey.ps1 | `public/New-DbaDbAsymmetricKey.ps1` | 132-215行目で非対称キー作成処理を確認 |

**主要処理フロー**:
- **135-137行目**: SqlInstance指定時にGet-DbaDatabase でデータベースオブジェクトを取得
- **140-143行目**: Name未指定時にデータベース名をデフォルトとして使用
- **146-148行目**: 既存キーの存在チェック
- **156行目**: SMO AsymmetricKeyオブジェクトの作成
- **157-164行目**: Owner検証とセット
- **165-199行目**: KeySourceTypeに応じた分岐処理とキー作成
- **201-206行目**: dbatools固有プロパティの追加（Add-Member）
- **207行目**: Select-DefaultViewで表示プロパティを設定

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

```
New-DbaDbAsymmetricKey
    │
    ├─ [begin]
    │   └─ Test-Bound (KeySource/KeySourceType検証)
    │
    └─ [process]
        │
        ├─ Get-DbaDatabase (SqlInstance指定時)
        │      └─ 対象データベースオブジェクトの取得
        │
        ├─ $db.AsymmetricKeys[$askey]
        │      └─ 既存キーの存在確認
        │
        ├─ Get-DbaDbUser (Owner指定時)
        │      └─ ユーザー存在確認
        │
        ├─ Test-DbaPath (KeySource指定時)
        │      └─ ファイル/パスの存在確認
        │
        ├─ Get-DbaDbAssembly (SqlAssemblyの場合)
        │      └─ アセンブリ存在確認
        │
        ├─ Microsoft.SqlServer.Management.Smo.AsymmetricKey
        │      └─ SMOオブジェクト作成
        │
        └─ AsymmetricKey.Create()
               └─ 非対称キー作成実行
```

### データフロー図

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

SqlInstance ───────▶ Get-DbaDatabase ──────────▶ Databaseオブジェクト
      │                  │
Database ─┼──────────────┘
      │
Name ─────┼────────────────────────────────────▶ キー名決定
      │
Owner ────┼───▶ Get-DbaDbUser ─────────────────▶ 所有者検証
      │                  │
KeySource ┼───▶ Test-DbaPath ─────────────────▶ ソース検証
      │                  │
Algorithm ┼────────────────┼─▶ SMO AsymmetricKey
      │                  │      │
SecurePassword ──────────┼──────┼─▶ Create()
                         │      │      │
                         ▼      ▼      ▼
                    AsymmetricKeyオブジェクト
                              │
                              ▼
                    Add-Member (dbatools プロパティ追加)
                              │
                              ▼
                    Select-DefaultView (表示プロパティ)
                              │
                              ▼
                    出力 (AsymmetricKey + dbatools プロパティ)
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| New-DbaDbAsymmetricKey.ps1 | `public/New-DbaDbAsymmetricKey.ps1` | ソース | メイン機能実装 |
| Get-DbaDatabase.ps1 | `public/Get-DbaDatabase.ps1` | ソース | データベースオブジェクト取得 |
| Get-DbaDbUser.ps1 | `public/Get-DbaDbUser.ps1` | ソース | データベースユーザー確認 |
| Get-DbaDbAssembly.ps1 | `public/Get-DbaDbAssembly.ps1` | ソース | SQLアセンブリ確認 |
| Test-DbaPath.ps1 | `public/Test-DbaPath.ps1` | ソース | SQL Serverからのパスアクセス確認 |
| Test-Bound.ps1 | `private/functions/Test-Bound.ps1` | ソース | パラメータバインド状態確認 |
| ConvertFrom-SecurePass.ps1 | `private/functions/ConvertFrom-SecurePass.ps1` | ソース | SecureString変換 |
