# 画面設計書 31-暗号化キー管理

## 概要

本ドキュメントは、dbatoolsにおけるデータベース暗号化キー管理機能の設計仕様を定義する。

### 本画面の処理概要

データベース暗号化キー管理機能は、Transparent Data Encryption（TDE）に必要なデータベース暗号化キー（DEK）の取得・作成・削除を行うPowerShellコマンド群を提供する。

**業務上の目的・背景**：データベースの暗号化はセキュリティコンプライアンスの重要な要素であり、保存データの保護（Data at Rest）を実現するためにTDEが広く使用されている。本機能は、TDE実装に必要な暗号化キーのライフサイクル管理を自動化し、セキュリティ監査やコンプライアンスレポートの作成を支援する。暗号化キーの状態確認、新規作成、適切な削除を一元的に管理することで、DBAの運用負荷を軽減する。

**画面へのアクセス方法**：PowerShellコンソールまたはスクリプトから以下のコマンドを実行してアクセスする。
- `Get-DbaDbEncryptionKey` - 暗号化キーの取得
- `New-DbaDbEncryptionKey` - 暗号化キーの作成
- `Remove-DbaDbEncryptionKey` - 暗号化キーの削除

**主要な操作・処理内容**：
1. 暗号化キー情報の取得：指定されたSQLインスタンス・データベースのTDE暗号化キーの詳細情報を取得
2. 暗号化キーの作成：証明書または非対称キーを使用してデータベース暗号化キーを新規作成
3. 暗号化キーの削除：TDE無効化後に不要になった暗号化キーを削除
4. 暗号化状態の監視：暗号化の進行状態（EncryptionState）の確認

**画面遷移**：本機能はCLIベースのため画面遷移は存在しないが、以下のコマンド間で連携が可能。
- `Get-DbaDatabase` から `Get-DbaDbEncryptionKey` へパイプライン入力
- `Get-DbaDbEncryptionKey` から `Remove-DbaDbEncryptionKey` へパイプライン入力
- データベース暗号化管理（No.30）との連携

**権限による表示制御**：暗号化キーの操作にはデータベースのCONTROL権限またはdb_owner固定データベースロールのメンバーシップが必要。証明書を使用する場合はmasterデータベースへのアクセス権限も必要。

## 関連機能

| 機能No | 機能名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 599 | Get-DbaDbEncryptionKey | 主機能 | データベース暗号化キーの取得 |
| 607 | New-DbaDbEncryptionKey | 主機能 | データベース暗号化キーの作成 |
| 613 | Remove-DbaDbEncryptionKey | 主機能 | データベース暗号化キーの削除 |

## 画面種別

CLI（コマンドラインインターフェース）- PowerShellコマンド

## URL/ルーティング

N/A（PowerShellモジュールのコマンドとして提供）

## 入出力項目

### Get-DbaDbEncryptionKey

| 項目名 | 型 | 必須 | 説明 |
|--------|-----|------|------|
| SqlInstance | DbaInstanceParameter[] | - | 対象SQLインスタンス |
| SqlCredential | PSCredential | - | 代替認証情報 |
| Database | string[] | - | 対象データベース名 |
| ExcludeDatabase | string[] | - | 除外データベース名 |
| InputObject | Database[] | - | パイプライン入力用データベースオブジェクト |
| EnableException | switch | - | 例外処理の有効化 |

### New-DbaDbEncryptionKey

| 項目名 | 型 | 必須 | 説明 |
|--------|-----|------|------|
| SqlInstance | DbaInstanceParameter[] | - | 対象SQLインスタンス |
| SqlCredential | PSCredential | - | 代替認証情報 |
| Database | string[] | - | 対象データベース名（デフォルト: master） |
| EncryptorName | string | - | 証明書または非対称キーの名前 |
| Type | string | - | エンクリプタの種類（Certificate/AsymmetricKey） |
| EncryptionAlgorithm | string | - | 暗号化アルゴリズム（Aes128/Aes192/Aes256/TripleDes） |
| InputObject | Database[] | - | パイプライン入力用データベースオブジェクト |
| Force | switch | - | 証明書バックアップチェックをスキップ |
| EnableException | switch | - | 例外処理の有効化 |

### Remove-DbaDbEncryptionKey

| 項目名 | 型 | 必須 | 説明 |
|--------|-----|------|------|
| SqlInstance | DbaInstanceParameter[] | - | 対象SQLインスタンス |
| SqlCredential | PSCredential | - | 代替認証情報 |
| Database | string[] | 条件付き必須 | 対象データベース名（SqlInstance指定時必須） |
| InputObject | DatabaseEncryptionKey[] | - | パイプライン入力用暗号化キーオブジェクト |
| EnableException | switch | - | 例外処理の有効化 |

## 表示項目

### Get-DbaDbEncryptionKey / New-DbaDbEncryptionKey 出力

| 項目名 | 型 | 説明 |
|--------|-----|------|
| ComputerName | string | SQLサーバーのコンピュータ名 |
| InstanceName | string | SQLインスタンス名 |
| SqlInstance | string | 完全なSQLインスタンス名 |
| Database | string | データベース名 |
| CreateDate | DateTime | 暗号化キー作成日時 |
| EncryptionAlgorithm | string | 暗号化アルゴリズム |
| EncryptionState | string | 暗号化状態 |
| EncryptionType | string | エンクリプタの種類 |
| EncryptorName | string | 証明書/非対称キー名 |
| ModifyDate | DateTime | 最終変更日時 |
| OpenedDate | DateTime | 最終オープン日時 |
| RegenerateDate | DateTime | 最終再生成日時 |
| SetDate | DateTime | 最終設定日時 |
| Thumbprint | string | 証明書のサムプリント |

### Remove-DbaDbEncryptionKey 出力

| 項目名 | 型 | 説明 |
|--------|-----|------|
| ComputerName | string | SQLサーバーのコンピュータ名 |
| InstanceName | string | SQLインスタンス名 |
| SqlInstance | string | 完全なSQLインスタンス名 |
| Database | string | データベース名 |
| Status | string | 操作結果（Success） |

## イベント仕様

### 1-暗号化キー取得

Get-DbaDbEncryptionKeyコマンド実行時：
1. SqlInstance指定時はGet-DbaDatabase経由でデータベースオブジェクトを取得
2. 各データベースのアクセシビリティを確認
3. DatabaseEncryptionKeyプロパティからEncryptionAlgorithmが設定されているキーを抽出
4. カスタムプロパティ（ComputerName、InstanceName等）を追加して出力

### 2-暗号化キー作成

New-DbaDbEncryptionKeyコマンド実行時：
1. 既存の暗号化キーの存在確認（既存の場合はエラー）
2. EncryptorName未指定時はmasterデータベースから適切な証明書/非対称キーを自動選択
3. 証明書使用時はバックアップ状態を確認（未バックアップ時は-Force必要）
4. SMOのDatabaseEncryptionKeyオブジェクトを作成してCreate()メソッドを実行
5. 作成後のキー情報をGet-DbaDbEncryptionKey経由で返却

### 3-暗号化キー削除

Remove-DbaDbEncryptionKeyコマンド実行時：
1. 対象の暗号化キーオブジェクトを取得
2. ShouldProcess確認（-Confirmまたは-WhatIf対応）
3. DROP DATABASE ENCRYPTION KEYクエリを実行
4. 結果ステータスを返却

## データベース更新仕様

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

| 操作（イベント） | 対象テーブル | 操作種別 | 概要 |
|----------------|-------------|---------|------|
| 暗号化キー取得 | sys.dm_database_encryption_keys | SELECT | 暗号化キー情報の参照 |
| 暗号化キー作成 | sys.dm_database_encryption_keys | INSERT | 新規暗号化キーの作成 |
| 暗号化キー削除 | sys.dm_database_encryption_keys | DELETE | 暗号化キーの削除 |

### テーブル別更新項目詳細

#### sys.dm_database_encryption_keys

| 操作 | 項目（カラム名） | 更新値・取得条件 | 備考 |
|-----|-----------------|-----------------|------|
| INSERT | encryption_algorithm | 指定されたアルゴリズム値 | Aes256がデフォルト |
| INSERT | encryptor_type | ServerCertificate/ServerAsymmetricKey | Type指定による |
| INSERT | encryptor_thumbprint | 証明書のサムプリント | 証明書から自動取得 |
| DELETE | - | DROP DATABASE ENCRYPTION KEY | TDE無効化後に実行 |

## メッセージ仕様

| メッセージID | 種別 | メッセージ内容 | 表示条件 |
|-------------|------|--------------|----------|
| MSG001 | 情報 | No encryption key exists in the {database} database on {instance} | 暗号化キーが存在しない場合 |
| MSG002 | 警告 | {database} is not accessible, skipping | データベースにアクセスできない場合 |
| MSG003 | エラー | {database} on {instance} already has a database encryption key | 既存キーが存在する場合 |
| MSG004 | エラー | No usable certificates found in master on {instance} | 使用可能な証明書がない場合 |
| MSG005 | エラー | Certificate ({name}) in master on {instance} has not been backed up | 証明書未バックアップ時 |
| MSG006 | エラー | Failed to create encryption key in {database} on {instance} | キー作成失敗時 |
| MSG007 | 成功 | Successfully removed encryption key from the {database} database on {server} | キー削除成功時 |
| MSG008 | エラー | Failed to drop encryption key from {database} on {server} | キー削除失敗時 |
| MSG009 | エラー | You must specify Database when using the SqlInstance parameter | 必須パラメータ不足時 |

## 例外処理

| 例外条件 | 処理内容 |
|---------|---------|
| データベースにアクセスできない | 警告メッセージを出力してスキップ |
| 暗号化キーが既に存在する | Stop-Functionでエラー出力して続行 |
| 証明書が見つからない | Stop-Functionでエラー出力して続行 |
| 証明書がバックアップされていない | -Forceフラグがない場合はエラー出力 |
| キー作成失敗 | Stop-Functionでエラー出力して続行 |
| キー削除失敗 | Stop-Functionでエラー出力して続行 |
| 接続エラー | Stop-Functionでエラー出力して続行 |

## 備考

- TDEを有効化する前に、暗号化キーの作成が必要
- 暗号化キーを削除する前に、ALTER DATABASE [database] SET ENCRYPTION OFFでTDEを無効化する必要がある
- 証明書のバックアップは必須であり、バックアップがない場合は-Forceフラグを使用する必要がある
- Aes256が推奨される暗号化アルゴリズムである
- SQL Server 2008以降でサポート

---

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

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

### 推奨読解順序

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

暗号化キー管理で扱う主要なデータ構造はSMOのDatabaseEncryptionKeyオブジェクトである。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | Get-DbaDbEncryptionKey.ps1 | `public/Get-DbaDbEncryptionKey.ps1` | 出力オブジェクトの構造（行45-65）を確認 |

**読解のコツ**: .OUTPUTSセクションでMicrosoft.SqlServer.Management.Smo.DatabaseEncryptionKeyの出力プロパティを確認する。

#### Step 2: エントリーポイントを理解する

各コマンドのprocess{}ブロックが処理の起点となる。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | Get-DbaDbEncryptionKey.ps1 | `public/Get-DbaDbEncryptionKey.ps1` | 行101-128のprocessブロック |
| 2-2 | New-DbaDbEncryptionKey.ps1 | `public/New-DbaDbEncryptionKey.ps1` | 行122-197のprocessブロック |
| 2-3 | Remove-DbaDbEncryptionKey.ps1 | `public/Remove-DbaDbEncryptionKey.ps1` | 行81-110のprocessブロック |

**主要処理フロー（Get-DbaDbEncryptionKey）**:
1. **行102-104**: SqlInstance指定時はGet-DbaDatabase経由でデータベース取得
2. **行106-110**: データベースのアクセシビリティチェック
3. **行112**: DatabaseEncryptionKeyプロパティからキー抽出
4. **行119-126**: カスタムプロパティ追加と出力

#### Step 3: 暗号化キー作成処理を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | New-DbaDbEncryptionKey.ps1 | `public/New-DbaDbEncryptionKey.ps1` | 証明書自動選択ロジック（行132-152） |
| 3-2 | New-DbaDbEncryptionKey.ps1 | `public/New-DbaDbEncryptionKey.ps1` | キー作成ロジック（行174-194） |

**主要処理フロー（New-DbaDbEncryptionKey）**:
- **行128-130**: 既存キーの存在確認
- **行132-152**: EncryptorName未指定時の自動選択
- **行156-167**: 証明書バックアップ確認
- **行176-181**: SMOオブジェクト作成とCreate()実行

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

```
Get-DbaDbEncryptionKey
    │
    ├─ Get-DbaDatabase (SqlInstance指定時)
    │      └─ Connect-DbaInstance
    │
    └─ Select-DefaultView (出力整形)

New-DbaDbEncryptionKey
    │
    ├─ Get-DbaDatabase
    │
    ├─ Get-DbaDbCertificate (証明書取得)
    │
    ├─ Get-DbaDbAsymmetricKey (非対称キー取得時)
    │
    ├─ New-DbaDbCertificate (-Force時に自動作成)
    │
    └─ Get-DbaDbEncryptionKey (作成後の確認)

Remove-DbaDbEncryptionKey
    │
    ├─ Get-DbaDbEncryptionKey (対象キー取得)
    │
    └─ Invoke-DbaQuery (DROP DATABASE ENCRYPTION KEY)
```

### データフロー図

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

SqlInstance    ───▶  Connect-DbaInstance
                            │
Database       ───▶  Get-DbaDatabase         ───▶  Database[]
                            │
                     DatabaseEncryptionKey    ───▶  DatabaseEncryptionKey[]
                     プロパティ取得                  (カスタムプロパティ追加済み)
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| Get-DbaDbEncryptionKey.ps1 | `public/Get-DbaDbEncryptionKey.ps1` | ソース | 暗号化キー取得コマンド |
| New-DbaDbEncryptionKey.ps1 | `public/New-DbaDbEncryptionKey.ps1` | ソース | 暗号化キー作成コマンド |
| Remove-DbaDbEncryptionKey.ps1 | `public/Remove-DbaDbEncryptionKey.ps1` | ソース | 暗号化キー削除コマンド |
| Get-DbaDatabase.ps1 | `public/Get-DbaDatabase.ps1` | ソース | データベース取得（依存コマンド） |
| Get-DbaDbCertificate.ps1 | `public/Get-DbaDbCertificate.ps1` | ソース | 証明書取得（依存コマンド） |
| Connect-DbaInstance.ps1 | `public/Connect-DbaInstance.ps1` | ソース | インスタンス接続（依存コマンド） |
| Invoke-DbaQuery.ps1 | `public/Invoke-DbaQuery.ps1` | ソース | クエリ実行（依存コマンド） |
