SQL Server Always Encrypted
クライアントサイドの列暗号化 — SQL エンジンは、管理者としてであっても、保護された列の平文を見ることはありません。
これは SQL EKM ではありません
DuoKey は 2 つの異なる SQL Server 統合をドキュメント化しており、それぞれ解決する課題が異なります。
- SQL EKM(Extensible Key Management)は、SQL Server の Transparent Data Encryption を保護します。SQL エンジン自身のデータベースマスターキーが DuoKey で保持されるキーによってラップされ、エンジンがすべてのテーブル/テーブルスペースの暗号化を透過的に処理します。SQL エンジンはクエリ時に平文を見ます — TDE が保護するのは保存時のデータファイルだけです。
- Always Encrypted(このページ)はクライアントサイドの列暗号化です。DuoKey が預かるのは、列ごとの列暗号化キー(CEK)をラップする列マスターキー(CMK)だけです。SQL エンジンではなくクライアントドライバーが、DuoKey のキープロバイダーを通じて CEK を取得・アンラップし、特定の列をローカルで暗号化/復号します。それらの列の平文が SQL エンジンに到達することは一切ありません — メモリ上にも、クエリプランにも、アドホックな
SELECTを実行する DBA に対しても現れません。
「SQL Server の管理者が列の平文を決して見られないようにする」ことが要件であれば、必要なのは SQL EKM ではなく Always Encrypted です。「ディスク上のデータファイルを暗号化する」ことが要件であれば、SQL EKM の TDE 統合が適切なツールです。
| SQL EKM(TDE) | Always Encrypted(このページ) | |
|---|---|---|
| 暗号化される対象 | 保存時のデータファイルとログファイル | 特定の列の値、エンドツーエンドで |
| 平文を見られるのは誰か | SQL エンジン — および適切なデータベース権限を持つ者 — がクエリ時に平文を見ます | CEK を保持するクライアントアプリケーションのみ。SQL エンジンと DBA が保護された列の平文を見ることはありません |
| DuoKey の役割 | 暗号化プロバイダー DLL を介して、エンジンに対して透過的にデータベースマスターキーをラップします | 列マスターキーを預かり、クライアントドライバーがそれを通じて CEK を取得・アンラップします |
| 復号が行われる場所 | SQL Server エンジンの内部 | SQL Server とのネットワークラウンドトリップの前後、クライアントドライバーの内部 |
概要
SQL Server の Always Encrypted は、特定の列をエンドツーエンドで保護します。保護される各列は列暗号化キー(CEK)で暗号化され、すべての CEK は列マスターキー(CMK)によってラップされます。CMK がデータベースに現れることは一切ありません — SQL Server が保存するのは、CMK のキーストアプロバイダー名とキーパスというメタデータ、およびラップされた(暗号化された)形式の CEK だけです。
このアプリは DuoKey をその CMK ストアプロバイダーにします。DuoKey のキープロバイダー(CNG/CSP、または Azure Key Vault 形式のエンドポイント)が実際の CMK を保持し、クライアントドライバーは必要に応じてそれを呼び出して CEK をアンラップします。
SQL Server が保存するのは、CMK のキーストアプロバイダー名とキーパスというメタデータ、および各 CEK のラップされた形式だけです。
| プロパティ | 値 |
|---|---|
| 暗号化モデル | クライアントサイドの列暗号化(CMK が列ごとの CEK をラップ) |
| キーのカストディ | DuoKey vault のキーが CMK として機能します。SQL エンジンが CEK や列の平文を保持することはありません |
| オンボーディング | アプリ詳細ページとカタログエントリ — ウィザードのエントリなし |
| 実証ステータス | CMK パスと T-SQL セットアップの生成は実物。セルフテストは現時点ではシミュレーション結果を返します — 下記参照 |
設定
| フィールド | 目的 | ||
|---|---|---|---|
sql_host | sql_port | database | 対象の SQL Server インスタンスとデータベース(デフォルトポートは 1433)。 |
cmk_store_provider | SQL ドライバーに通知されるプロバイダー名: `DUOKEY_CNG`(デフォルト)、`AZURE_KEY_VAULT`、または証明書ストアのプロバイダー。 | ||
cmk_name | SQL Server における列マスターキーオブジェクトの論理名。デフォルトは `DuoKey_CMK` です。 | ||
linked_key_id | すべての CEK をラップする CMK を支える DuoKey vault のキー。 | ||
enclave_enabled | セキュアエンクレーブ(VBS または Intel SGX)による列暗号化を要求するかどうか。セキュアエンクレーブとは、SQL Server エンジンプロセス内部にある保護され構成証明されたメモリ領域であり、そこではエンジンがランダム暗号化された列に対して、より高度な操作 — 比較、`BETWEEN`、`IN`、`LIKE`、結合、および(SQL Server 2022+ / Azure SQL Database では)`GROUP BY` / `ORDER BY` — を直接実行でき、平文やキーをエンクレーブの外に一切さらすことなく列をその場で再暗号化できます。エンクレーブ対応の CMK/CEK オブジェクトと、ドライバー側の構成証明の設定が必要であり、ここでは今後のドキュメント化の対象です。 |
列が暗号化・復号される仕組み
ステップ 2〜4 は完全にクライアントドライバー内で行われ、SQL エンジンが CEK や列の平文を保持することはありません。
SQL Server 自身がアンラップや暗号化/復号を行うことはありません — 上記のステップ 2〜4 は完全にクライアント側で行われます。そのため、セキュアエンクレーブがない場合、Always Encrypted は DETERMINISTIC の列に対する等価系の操作(=、IN、GROUP BY、DISTINCT)のみをサポートし、RANDOMIZED の列に対しては一切の操作をサポートしません。エンジンには、見ることのできない値を比較する手段がないためです。
セットアップ T-SQL
デプロイすると、列マスターキーと最初の列暗号化キー、および列を暗号化する例が生成されます。
CREATE COLUMN MASTER KEY [DuoKey_CMK]
WITH (
KEY_STORE_PROVIDER_NAME = N'DUOKEY_CNG',
KEY_PATH = N'DUOKEY_CNG/<tenant-id>/DuoKey_CMK'
);-- ENCRYPTED_VALUE is produced by the DuoKey key provider wrapping
-- a fresh CEK with the CMK above; the create-CEK action generates it.
CREATE COLUMN ENCRYPTION KEY [CEK_Auto1]
WITH VALUES (
COLUMN_MASTER_KEY = [DuoKey_CMK],
ALGORITHM = 'RSA_OAEP',
ENCRYPTED_VALUE = 0x<wrapped-cek-hex>
);ALTER TABLE <schema>.<table>
ALTER COLUMN <column> <type>
ENCRYPTED WITH (
COLUMN_ENCRYPTION_KEY = [CEK_Auto1],
ENCRYPTION_TYPE = DETERMINISTIC,
ALGORITHM = 'AEAD_AES_256_CBC_HMAC_SHA_256'
);DETERMINISTIC は暗号化された列に対する等価検索と結合を可能にしますが、どの行が同じ値を共有しているかが漏れるという代償があります。RANDOMIZED はより強力な保護を提供しますが、その列を WHERE、JOIN、GROUP BY、またはインデックスで使用することはできません。
列暗号化キーの作成とローテーション
デプロイ時に作成される CEK に加えて、このアプリは同じ CMK の下で CEK を追加またはローテーションするための専用の操作を提供します — 追加の列を暗号化する場合や、CMK に触れずに CEK をローテーションする場合に便利です。
| フィールド | 目的 |
|---|---|
cek_name | SQL Server における CEK の論理名。例: `CEK_Auto2`。 |
レスポンスでは、ドライバーが解決する完全修飾の CMK キーパス(<provider>/<tenant>/<cmk_name> — 秘密ではない不透明な座標)と、実行すべき CREATE COLUMN ENCRYPTION KEY 文が返されます。
ヘルスとセルフテスト
| チェック | 報告される内容 | 現時点でのライブプローブ |
|---|---|---|
| ヘルス | SQL への到達性、CMK へのアクセス可否、CEK の数 | なし — 固定の正常ステータスエンベロープを返します |
| セルフテスト | SQL への接続、CMK へのアクセス、CEK のアンラップのラウンドトリップ、決定的な列の暗号化/復号 | なし — 4 つのチェックすべてがハードコードされた合格を返します |
セルフテストがライブの SQL Server セッションを実行するようになるまでは、Column Encryption Setting=Enabled のドライバーフラグを付けない接続で保護された列をクエリして、列暗号化が実際に有効であることを確認してください — 平文ではなく暗号文(varbinary)が表示されるはずです。