# 機能設計書 606-New-DbaDbCertificate

## 概要

本ドキュメントは、SQL Serverデータベースに暗号化およびセキュリティ目的の証明書を作成する`New-DbaDbCertificate`機能の設計書である。

### 本機能の処理概要

`New-DbaDbCertificate`は、SQL Server Management Objects（SMO）を使用して指定されたデータベースに新しいデータベース証明書を作成する機能である。データベース証明書は、Transparent Data Encryption（TDE）、ストアドプロシージャや関数の暗号化、Service Brokerダイアログのセキュリティ確保、列レベル暗号化の有効化に不可欠である。

**業務上の目的・背景**：企業のセキュリティ要件やコンプライアンス規制では、データベースレベルでの暗号化が求められることが多い。証明書はパスワードで保護するか、データベースマスターキーで保護することができ、有効期限やサブジェクト情報を構成可能である。データベースが指定されない場合、証明書はmasterデータベースに作成される。

**機能の利用シーン**：
- TDE（透過的データ暗号化）の実装準備
- Service Brokerでの暗号化通信の設定
- 列レベル暗号化の実装
- ストアドプロシージャや関数のデジタル署名

**主要な処理内容**：
1. ターゲットデータベースへの接続（Get-DbaDatabase経由）
2. 既存の証明書存在チェック
3. SMO Certificateオブジェクトの作成と構成（StartDate, ExpirationDate, Subject等）
4. 証明書の作成（パスワード保護またはマスターキー保護）
5. dbatools固有プロパティの追加と結果出力

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

**権限による制御**：データベースへのCREATE CERTIFICATE権限が必要。

## 関連画面

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

## 機能種別

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

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| SqlInstance | DbaInstanceParameter[] | No | ターゲットSQL Serverインスタンス | なし |
| SqlCredential | PSCredential | No | SQL Server接続用の代替資格情報 | なし |
| Name | String[] | No | 証明書名（デフォルト: データベース名） | なし |
| Database | String[] | No | 証明書を作成するデータベース（デフォルト: master） | なし |
| Subject | String[] | No | 証明書のサブジェクトフィールド（デフォルト: "[DatabaseName] Database Certificate"） | なし |
| StartDate | DateTime | No | 証明書が有効になる日時（デフォルト: 現在日時） | なし |
| ExpirationDate | DateTime | No | 証明書の有効期限（デフォルト: StartDateから5年後） | なし |
| ActiveForServiceBrokerDialog | Switch | No | Service Brokerダイアログセキュリティに対する有効化 | なし |
| SecurePassword | SecureString | No | 証明書の秘密鍵を暗号化するパスワード | なし |
| InputObject | Database[] | No | Get-DbaDatabase からパイプライン入力 | なし |
| EnableException | Switch | No | 例外処理の有効化フラグ | なし |

### 入力データソース

- SQL Server SMO

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| ComputerName | String | SQL Serverインスタンスのコンピュータ名 |
| InstanceName | String | SQL Serverインスタンス名 |
| SqlInstance | String | 完全なSQL Serverインスタンス名（コンピュータ\インスタンス形式） |
| Database | String | 証明書が作成されたデータベース名 |
| Name | String | 証明書の名前 |
| Subject | String | 証明書のサブジェクトフィールド |
| StartDate | DateTime | 証明書が有効になる日時 |
| ActiveForServiceBrokerDialog | Boolean | Service Brokerダイアログに対して有効かどうか |
| ExpirationDate | DateTime | 証明書の有効期限 |
| Issuer | String | 証明書の発行者 |
| LastBackupDate | DateTime | 証明書の最後のバックアップ日時 |
| Owner | String | 証明書を所有するプリンシパル |
| PrivateKeyEncryptionType | String | 秘密鍵の暗号化タイプ（None, Password, MasterKey） |
| Serial | String | 証明書のシリアル番号 |

### 出力先

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

## 処理フロー

### 処理シーケンス

```
1. 各InputObject（データベース）に対して処理（processブロック）
   ├─ SqlInstanceが指定された場合はGet-DbaDatabase で取得
   ├─ Name未指定時はデータベース名を使用
   ├─ Subject未指定時は"[Name] Database Certificate"を使用
   ├─ Certificates.Refresh()で最新状態を取得
   ├─ 既存の証明書存在チェック
   ├─ SMO Certificateオブジェクトの作成と構成
   │   └─ StartDate, Subject, ExpirationDate, ActiveForServiceBrokerDialog設定
   └─ Certificate.Create()で証明書を作成
       └─ パスワード保護またはマスターキー保護
```

### フローチャート

```mermaid
flowchart TD
    A[開始] --> B[データベースループ開始]
    B --> C{Name指定?}
    C -->|No| D[データベース名を使用]
    C -->|Yes| E[指定名を使用]
    D --> F{Subject指定?}
    E --> F
    F -->|No| G["[Name] Database Certificate"を使用]
    F -->|Yes| H[指定Subjectを使用]
    G --> I[Certificates.Refresh]
    H --> I
    I --> J{既存証明書存在?}
    J -->|存在| K[エラー出力してスキップ]
    J -->|存在しない| L[SMO Certificate作成]
    L --> M[プロパティ設定]
    M --> N{SecurePassword指定?}
    N -->|Yes| O[パスワード付きCreate]
    N -->|No| P[マスターキー保護Create]
    O --> Q[dbatools プロパティ追加]
    P --> Q
    Q --> R[結果出力]
    R --> S{次のデータベース?}
    K --> S
    S -->|Yes| B
    S -->|No| T[終了]
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-606-01 | デフォルトデータベース | Database未指定時はmasterを使用 | Database未指定時 |
| BR-606-02 | デフォルト証明書名 | Name未指定時はデータベース名を使用 | Name未指定時 |
| BR-606-03 | デフォルトサブジェクト | Subject未指定時は"[Name] Database Certificate"を使用 | Subject未指定時 |
| BR-606-04 | デフォルト開始日 | StartDate未指定時は現在日時を使用 | StartDate未指定時 |
| BR-606-05 | デフォルト有効期限 | ExpirationDate未指定時はStartDateから5年後 | ExpirationDate未指定時 |
| BR-606-06 | 重複証明書禁止 | 同名の証明書が既に存在する場合はエラー | 常時 |
| BR-606-07 | パスワード保護 | SecurePassword指定時はパスワードで保護、未指定時はマスターキーで保護 | 常時 |

### 計算ロジック

**ExpirationDate計算**：
- `$ExpirationDate = $StartDate.AddYears(5)`

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

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

| 操作 | 対象テーブル | 操作種別 | 概要 |
|-----|-------------|---------|------|
| 証明書作成 | sys.certificates | INSERT | 証明書レコードの作成 |

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

#### sys.certificates

| 操作 | 項目（カラム名） | 更新値・取得条件 | 備考 |
|-----|-----------------|-----------------|------|
| INSERT | name | 指定された証明書名 | Name パラメータまたはデータベース名 |
| INSERT | subject | 指定されたサブジェクト | Subject パラメータまたはデフォルト値 |
| INSERT | start_date | 開始日時 | StartDate パラメータまたは現在日時 |
| INSERT | expiry_date | 有効期限日時 | ExpirationDate パラメータまたは5年後 |
| INSERT | pvt_key_encryption_type | 秘密鍵暗号化タイプ | MK（マスターキー）, PW（パスワード） |

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| - | 重複エラー | 同名の証明書が既に存在 | 別の名前を使用 |
| - | 権限エラー | CREATE CERTIFICATE権限なし | 適切な権限を付与 |
| - | マスターキーなし | パスワード未指定でマスターキーが存在しない | パスワードを指定するかマスターキーを作成 |
| - | 作成失敗 | SMO操作でエラー発生 | エラーメッセージを確認 |

### リトライ仕様

特になし

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

SMOによる証明書作成は暗黙のトランザクション内で実行される

## パフォーマンス要件

特に規定なし

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

- CREATE CERTIFICATE権限が必要
- パスワード保護なしの場合、データベースマスターキーで保護される
- 証明書はバックアップして安全に保管することを推奨
- 有効期限切れの証明書は暗号化されたデータへのアクセスに影響するため、計画的な更新が必要
- SecurePasswordはSecureString型で安全に取り扱われる

## 備考

- TDE用途では通常、masterデータベースに証明書を作成する
- 証明書のバックアップを行うにはBackup-DbaDbCertificateを使用
- Service Brokerで使用する場合はActiveForServiceBrokerDialogを有効にする

---

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

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

### 推奨読解順序

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

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

**読解のコツ**: SMO Certificateオブジェクトをラップしてdbatools固有のプロパティを追加している点に注目。ExpirationDateのデフォルト計算（$StartDate.AddYears(5)）がparamブロック内で行われている。

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | New-DbaDbCertificate.ps1 | `public/New-DbaDbCertificate.ps1` | 130-186行目で証明書作成処理を確認 |

**主要処理フロー**:
- **131-133行目**: SqlInstance指定時にGet-DbaDatabase でデータベースオブジェクトを取得
- **136-139行目**: Name未指定時にデータベース名をデフォルトとして使用
- **141-144行目**: Subject未指定時にデフォルトサブジェクトを設定
- **147-148行目**: Certificates.Refresh()と既存証明書チェック
- **158行目**: SMO Certificateオブジェクトの作成
- **159-162行目**: プロパティ設定（StartDate, Subject, ExpirationDate, ActiveForServiceBrokerDialog）
- **164-170行目**: パスワード有無に応じた証明書作成
- **172-177行目**: dbatools固有プロパティの追加

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

```
New-DbaDbCertificate
    │
    └─ [process]
        │
        ├─ Get-DbaDatabase (SqlInstance指定時)
        │      └─ 対象データベースオブジェクトの取得
        │
        ├─ Test-Bound (Name, Subject未指定チェック)
        │      └─ パラメータバインド状態確認
        │
        ├─ $db.Certificates.Refresh()
        │      └─ 証明書コレクションの更新
        │
        ├─ $db.Certificates[$cert]
        │      └─ 既存証明書の存在確認
        │
        ├─ Microsoft.SqlServer.Management.Smo.Certificate
        │      └─ SMOオブジェクト作成
        │
        ├─ Certificate.Create()
        │      └─ 証明書作成実行
        │           └─ ConvertFrom-SecurePass (パスワード指定時)
        │
        ├─ Add-Member
        │      └─ dbatools プロパティ追加
        │
        └─ Select-DefaultView
               └─ 表示プロパティ設定
```

### データフロー図

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

SqlInstance ───────▶ Get-DbaDatabase ──────────▶ Databaseオブジェクト
      │                  │
Database ─┼──────────────┘
      │
Name ─────┼────────────────────────────────────▶ 証明書名決定
      │
Subject ──┼────────────────────────────────────▶ サブジェクト決定
      │
StartDate ┼────────────────────────────────────▶ 開始日設定
      │
ExpirationDate ───────────────────────────────▶ 有効期限設定
      │                                              │
ActiveForServiceBrokerDialog ──────────────────────▶ │
      │                                              │
      │                  ▼                           ▼
      │          SMO Certificate オブジェクト作成・設定
      │                  │
SecurePassword ──────────┼─▶ Create()
                         │      │
                         ▼      ▼
                    Certificateオブジェクト
                              │
                              ▼
                    Add-Member (dbatools プロパティ追加)
                              │
                              ▼
                    Select-DefaultView (表示プロパティ)
                              │
                              ▼
                    出力 (Certificate + dbatools プロパティ)
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| New-DbaDbCertificate.ps1 | `public/New-DbaDbCertificate.ps1` | ソース | メイン機能実装 |
| Get-DbaDatabase.ps1 | `public/Get-DbaDatabase.ps1` | ソース | データベースオブジェクト取得 |
| Test-Bound.ps1 | `private/functions/Test-Bound.ps1` | ソース | パラメータバインド状態確認 |
| ConvertFrom-SecurePass.ps1 | `private/functions/ConvertFrom-SecurePass.ps1` | ソース | SecureString変換 |
| Get-DbaDbCertificate.ps1 | `public/Get-DbaDbCertificate.ps1` | ソース | 証明書取得（関連機能） |
| Backup-DbaDbCertificate.ps1 | `public/Backup-DbaDbCertificate.ps1` | ソース | 証明書バックアップ（関連機能） |
