どのようなときに Azure SQL Database Always Encrypted を使用するかを推奨する
Always Encrypted は、Azure SQL Database、Azure SQL Managed Instance、および SQL Server データベースに格納された、クレジット カード番号や国と地域の識別番号 (米国の社会保障番号など) のような機密データを保護することを目的とした機能です。 Always Encrypted では、クライアント内部で機密データが暗号化されるため、暗号化キーがデータベース エンジンに公開されることはありません。 Always Encrypted では、データを所有していて表示できるユーザーと、データを管理するがアクセス権を持たないユーザー (オンプレミスのデータベース管理者、クラウド データベースオペレーター、その他の高い特権を持つ権限のないユーザー) との間で分離が提供されます。 その結果、Always Encrypted を使用すると、顧客は自信を持って機密データをクラウドに格納し、悪意のある内部関係者によるデータ盗難の可能性を減らすことができます。
Always Encrypted は、暗号化されたデータ (等価比較を伴うクエリ) に対する制限付き機密クエリをサポートするように構成できます。 たとえば、ポイント参照検索や等値結合などです。 このようなクエリでは、決定論的な暗号化が使用されます。
注
セキュリティで保護されたエンクレーブは、パターン マッチング、他の比較演算子、インプレース暗号化を使用して Always Encrypted のコンフィデンシャル コンピューティング機能を拡張します。
Always Encrypted を使用すると、アプリケーションに対して暗号化が透過的になります。 クライアント コンピューターにインストールされている Always Encrypted 対応ドライバーは、クライアント アプリケーション内の機密データを自動的に暗号化および復号化します。 ドライバーは、データベース エンジンにデータを渡す前に、機密列のデータを暗号化します。 その後、ドライバーは自動的にクエリを書き換えて、アプリケーションのセマンティクスが保持されるようにします。 同様に、ドライバーは、暗号化されたデータベース列に格納されているデータをクエリ結果に含まれる透過的に復号化します。
Always Encrypted の構成
データベースで Always Encrypted を設定するには、次の操作を行う必要があります:
暗号化キーをデプロイしてデータを保護します。 Always Encrypted では 2 種類のキーを使用します。
- 列暗号化キー。
- 列マスター キー。
列暗号化キーは、暗号化された列のデータを暗号化するために使用されます。 列マスター キーは、1 つ以上の列暗号化キーを暗号化するキー保護キーです。 データベース システムの外部にある信頼されたキー ストアに列マスター キーを格納する必要があります。 最も一般的なストレージの場所は、Azure Key Vault、Windows 証明書ストア、またはハードウェア セキュリティ モジュールです。 次に、列暗号化キーをデプロイし、各キーを列マスター キーで暗号化する必要があります。 最後に、キーに関するメタデータをデータベースに格納する必要があります。
- 列マスター キーメタデータは、列マスター キーの場所をキャプチャします。
- 列暗号化キーのメタデータには、列暗号化キーの暗号化された値が含まれています。 データベース エンジンは、いずれの種類も、プレーンテキストで格納または使用しません。
保護する機密データを含む選択したデータベース列の暗号化を構成します。 暗号化された列を使用して新しいテーブルを作成することも、既存のデータベース列と既存のデータを暗号化することもできます。 列の暗号化を設定する場合は、暗号化アルゴリズムに関する情報、列内のデータを保護するための列暗号化キー、および暗号化の種類を指定します。 Always Encrypted では、次の 2 種類の暗号化がサポートされています。
- 決定論的な暗号化の場合、任意のたプレーンテキスト値に対して、同じ暗号化された値が常に生成されます。 決定論的暗号化を使用すると、ポイント参照、等値結合、グループ化、および暗号化された列のインデックス作成が可能になります。 ただし、承認されていないユーザーが暗号化された列のパターンを調べることで、暗号化された値に関する情報を推測することもできます。特に、True/False、North/South/East/West リージョンなど、可能な暗号化された値の小さなセットがある場合です。
- 暗号化をランダム化 は低い予測可能な方法でデータを暗号化するためのメソッドを使用します。 ランダム化された暗号化の方が安全ですが、暗号化された列での検索、グループ化、インデックス作成、結合を防ぐことができます。
検索パラメーターまたはグループ化パラメーターとして使用される列には、決定論的暗号化を使用します。 たとえば、身分登録番号などです。 他のレコードとグループ化されておらず、テーブルの結合に使用されていない信用調査情報などのデータについては、ランダム化された暗号化を使用します。 Always Encrypted による暗号化アルゴリズムの詳細については、「Always Encrypted による暗号」を参照してください。 SQL ツールを使用して、上記の手順を実行できます。
- SQL Server Management Studio (SSMS)
- SQL Server PowerShell
- sqlpackage - セットアップ プロセスを自動化する
Always Encrypted キーと保護対象の機密データがデータベース環境のプレーンテキストで絶対に暴露されないように、データベース エンジンがキー プロビジョニングに関与し、データ暗号化または復号化操作を実行することはできません。 そのため、Transact-SQL (T-SQL) では、キーのプロビジョニングや暗号化操作はサポートされません。 同じ理由で、既存のデータを暗号化するか、(異なる暗号化の種類または列暗号化キーを使用して) 再暗号化する必要があります(SQL ツールはそれを自動化できます)。
暗号化された列に対するクエリのしくみ
ユーザーが次のいずれかのアクションを実行する必要がある場合は、一連の前提条件を満たす必要があります。
- 暗号化されたデータベース列に対してクエリを実行する
- 暗号化された列にデータを挿入する
- 暗号化された列からプレーンテキスト値を取得する
- 決定論的暗号化を使用して列に対してサポートされている操作 (ポイント参照検索など) を実行する
クエリを発行するユーザーまたはアプリケーションは、次の前提条件を満たしている必要があります。
- データを保護する列マスター キーにアクセスできます。 データを含むテーブルの
SELECTなど、データベース レベルのアクセス許可に加えて、キー アクセスが必要です。 - データベース接続で Always Encrypted が有効になっているデータベースに接続します。 ほとんどの SQL ツールと SQL クライアント ドライバーは、データベース接続に対して Always Encrypted を有効にすることをサポートしています。
注
ユーザーがデータを読み取るために必要なデータベースアクセス許可を持っていても、それを保護するキーへのアクセス権がない場合は、アクションを実行できます。 ユーザーは、データベース接続で Always Encrypted を有効にせずにデータベースに接続することで、暗号テキスト (暗号化された) データを取得できます。
暗号化された列に対するクエリのしくみを次に示します:
- アプリケーションがパラメーター化されたクエリを発行すると、アプリケーション内の SQL クライアント ドライバーはデータベース エンジンに透過的に接続し ( sp_describe_parameter_encryption (Transact-SQL) を呼び出して、暗号化する必要がある列を対象とするパラメーターを決定します。 暗号化する必要がある各パラメーターについて、ドライバーは暗号化アルゴリズム、暗号化の種類、およびキー メタデータ (暗号化された列暗号化キーと、対応する列マスター キーの場所を含む) を受け取ります。
- ドライバーは、暗号化された列暗号化キーの値を復号化するために、列マスター キーを含むキー ストアを呼び出します。 以降、同じ列の暗号化キーを使用する際に、キー ストアに対するラウンド トリップ数を軽減するために、結果のプレーンテキスト列暗号化キーはキャッシュされます。
- ドライバーは、取得したプレーンテキスト列暗号化キーを使用して、暗号化された列に対応するクエリ パラメーターを暗号化します。
- ドライバーは、暗号化された列を対象とするパラメーターのプレーンテキスト値を、暗号化値と置き換え、処理を実行するデータベース エンジンにクエリを送信します。
- データベース エンジンはクエリを実行します。これには、決定論的暗号化を使用した列の等価比較が含まれる場合があります。
- クエリ結果に暗号化された列のデータが含まれている場合、データベース エンジンは、暗号化アルゴリズム、暗号化の種類、キー メタデータに関する情報を含む各列の暗号化メタデータを結果セットにアタッチします。
- データベース エンジンは、結果セットをクライアント アプリケーションに送信します。
- 受信した結果セット内の暗号化された列ごとに、ドライバーは最初にローカル キャッシュ内のプレーンテキスト列暗号化キーの検索を試み、キャッシュ内のキーが見つからない場合にのみ、列マスター キーを保持するキー ストアへのラウンド トリップを行います。
- ドライバーは結果を復号化し、プレーンテキスト値をアプリケーションに返します。
クライアント ドライバーは、列マスター キー ストア プロバイダーを使用して、列マスター キーを含むキー ストアに接続します。このプロバイダーは、列マスター キーを含むキー ストアをカプセル化するクライアント側ソフトウェア コンポーネントです。 キー ストアの一般的な種類のプロバイダーは、Microsoft からのクライアント側ドライバーのライブラリで、またはスタンドアロンのダウンロードとして入手できます。 独自のプロバイダーを実装することもできます。 組み込みの列マスター キー ストア プロバイダーを含む Always Encrypted の機能は、ドライバー ライブラリとそのバージョンによって異なります。
Always Encrypted をサポートするクライアント ドライバーの一覧と 、暗号化された 列にクエリを実行するアプリケーションを開発する方法については、「Always Encrypted を使用したアプリケーションの開発」を参照してください。
Azure Data Studio や SSMS などの SQL ツールを使用して、暗号化された列のクエリを実行することもできます。
制限事項
暗号化された列に対するクエリには、次の制限事項が適用されます:
等価比較に関連する次の操作が、決定論的な暗号化でサポートされています。他の操作は許可されません。
- ポイント検索の検索で = (等しい)。
- IN.
- SELECT - GROUP BY.
- DISTINCT.
- ポイント検索の検索で = (等しい)。
ランダム化された暗号化を使用して暗号化された列に対する計算は許可されません。
注
セキュリティで保護されたエンクレーブが設定された Always Encrypted では、ランダム化された暗号化を使用して、列のパターン マッチング、比較演算子、並べ替え、インデックス作成を許可することで、制限が緩和されます。
プレーンテキストと暗号化されたデータの両方を含む計算をトリガーするクエリ ステートメントは許可されません。 例えば次が挙げられます。
- 暗号化された列とプレーンテキスト列またはリテラルを比較します。
- プレーンテキスト列から暗号化された列 (またはその逆の方法で) UPDATE、BULK INSERT、SELECT INTO、または INSERT..SELECT へデータをコピー。
- 暗号化された列へのリテラルの挿入。
- 暗号化された列とプレーンテキスト列またはリテラルを比較します。
このようなステートメントでは、次のようなオペランドの競合エラーが発生します。
Output
Msg 206, Level 16, State 2, Line 89
Operand type clash: char(11) encrypted with (encryption_type = 'DETERMINISTIC', encryption_algorithm_name = 'AEAD_AES_256_CBC_HMAC_SHA_256', column_encryption_key_name = 'CEK_1', column_encryption_key_database_name = 'ssn') collation_name = 'Latin1_General_BIN2' is incompatible with char
アプリケーションでは、暗号化された列に対応する値を渡すためにクエリ パラメーターを使用する必要があります。 たとえば、暗号化された列にデータを挿入する場合や、暗号化された列でフィルター処理する場合 (決定論的暗号化を使用する場合)。 暗号化された列に対応するリテラルまたは T-SQL 変数の受け渡しはサポートされていません。 使用しているクライアント ドライバーに固有の詳細については、「Always Encrypted を使用したアプリケーションの開発」を参照してください。
これらのツールで暗号化された列に対応する値を渡すクエリを発行するには、Azure Data Studio または SSMS で Always Encrypted 変数のパラメーター化を使用する必要があります。 たとえば、暗号化された列にデータを挿入する場合や、暗号化された列でフィルター処理する場合 (決定論的暗号化を使用する場合)。
暗号化された列を対象にしたテーブル値パラメーターはサポートされていません。
次の句を使用するクエリはサポートされていません:
暗号化された列の定義を変更した後、sp_refresh_parameter_encryption を実行して、オブジェクトに対する Always Encrypted のメタデータを更新します。
以下の特性を持つ列に対しては、Always Encrypted はサポートされていません:
- 次のデータ型のいずれかを使用する列: xml、timestamp、rowversion、image、ntext、text、sql_variant、hierarchyid、geography、geometry、alias、ユーザー定義型。
- FILESTREAM 列
- IDENTITY プロパティを持つ列。
- ROWGUIDCOL プロパティを持つ列。
- 決定論的暗号化を使用する場合、バイナリ コード ポイント (_BIN2) 照合順序 以外の照合順序を持つ文字列 (varchar、char など) の列。
- ランダム化された暗号化を使用するときのクラスター化インデックスおよび非クラスター化インデックスのキーである列 (決定論的な暗号化を使った列のインデックスがサポートされています)。
- フルテキスト インデックスに含まれる列 (Always Encrypted でフルテキスト検索はサポートされていません)。
- 計算列。
- 計算列によって参照される列 (式が Always Encrypted でサポート外の演算を実行するとき)。
- スパース列セット。
- ランダム化された暗号化を使用する場合に 統計 によって参照される列 (決定論的暗号化がサポートされています)。
- パーティション分割列。
- 既定の制約を含む列。
- ランダムな暗号化を使用するときに UNIQUE 制約によって参照される列 (明確な暗号化はサポートされます)。
- ランダムな暗号化を使用するときの主キー列 (明確な暗号化はサポートされます)。
- ランダム化された暗号化または明確な暗号化を使用する際の、外部キー制約での列の参照 (参照元および参照先の列が異なるキーまたはアルゴリズムを使用する場合)。
- CHECK 制約によって参照される列。
- 変更データ キャプチャを使用してキャプチャまたは追跡される列。
- 変更の追跡を持つテーブル上の主キー列。
- マスキングされている列 (動的データ マスクを使用)。
- Stretch Database テーブル内の列。 (Always Encrypted で暗号化された列を持つテーブルは Stretch で有効にできます)。
Von Bedeutung
拡張データベースは、SQL Server 2022 (16.x) および Azure SQL Database では非推奨になります。 この機能は、データベース エンジンの将来のバージョンで削除される予定です。 新しい開発作業ではこの機能を使用しないでください。現在この機能を使用しているアプリケーションを変更することを計画してください。
次の機能は、暗号化された列では機能しません。
- SQL Server レプリケーション (トランザクション、マージ、またはスナップショット レプリケーション)。 Always を含む物理レプリケーション機能がサポートされています。
- 分散クエリ (リンク サーバー、OPENROWSET (Transact-SQL)、OPENDATASOURCE (Transact-SQL))。
- 異なるデータベースの列に対して結合を実行するデータベース間クエリ (決定論的暗号化を使用)。
Always Encrypted Transact-SQL リファレンス
Always Encrypted では、次の Transact-SQL ステートメント、システム カタログ ビュー、システム ストアド プロシージャ、およびアクセス許可が使用されます。
ステートメント
- 列マスターキーを作成 (Transact-SQL)
- 列マスターキーを削除 (Transact-SQL)
- 列暗号化キーの作成 (Transact-SQL)
- 列暗号化鍵の変更(Transact-SQL)
- 列暗号化キーを削除(Transact-SQL)
- テーブルを作成 (暗号化付き)
システム カタログ ビューとストアド プロシージャ
- sys.column_encryption_keys (Transact-SQL)
- sys.column_encryption_key_values (Transact-SQL)
- sys.column_master_keys (Transact-SQL)
- sp_refresh_parameter_encryption (Transact-SQL)
- sp_describe_parameter_encryption (Transact-SQL)
各列に格納されている暗号化メタデータについては、sys.columns (Transact-SQL) も参照してください。
データベースのアクセス許可
Always Encrypted には、次の 4 つのデータベースアクセス許可があります:
- ALTER ANY COLUMN MASTER KEY - 列マスター キーのメタデータを作成および削除するために必要です。
- ALTER ANY COLUMN ENCRYPTION KEY - 列暗号化キーのメタデータを作成および削除するために必要です。
- VIEW ANY COLUMN MASTER KEY DEFINITION - 暗号化された列のクエリに必要な列マスター キー メタデータにアクセスして読み取るために必要です。
- VIEW ANY COLUMN ENCRYPTION KEY DEFINITION - 暗号化された列のクエリに必要な列マスター キー メタデータにアクセスして読み取るために必要です。
次の表は、一般的な操作に必要なアクセス許可をまとめたものです。
| シナリオ | 任意の列マスターキーの変更 | 任意のカラム暗号化キーを変更 | 任意の列マスターキー定義の表示 | 列暗号化キーの定義を表示する |
|---|---|---|---|---|
| キー管理 (データベース内のキーの作成/変更/確認) | X | X | X | X |
| 暗号化された列のクエリ | X | X |
重要な考慮事項
- 暗号化された列を選択する場合は、列マスター キーに対するアクセス許可 (キー ストア内) がない場合でも、列を保護し、プレーンテキストの試行にアクセスしない場合でも、VIEW ANY COLUMN MASTER KEY DEFINITION および VIEW ANY COLUMN ENCRYPTION KEY DEFINITION 権限が必要です。
- SQL Server では、VIEW ANY COLUMN MASTER KEY DEFINITION 権限と VIEW ANY COLUMN ENCRYPTION KEY DEFINITION 権限の両方が、既定でパブリック固定データベース ロールに付与されます。 データベース管理者は、 パブリック ロールに対するアクセス許可を失効 (または拒否) し、特定のロールまたはユーザーに付与して、より制限が大きい制御を実装することができます。
- SQL Database では、VIEW ANY COLUMN MASTER KEY DEFINITION 権限と VIEW ANY COLUMN ENCRYPTION KEY DEFINITION 権限が、既定でパブリック固定データベース ロールに付与されます。 これによって、(旧バージョンの DacFx を使用する) 一部の既存のレガシ ツールが正常に動作するようになります。 暗号化された列を操作するには (暗号化を解除しない場合でも)、データベース管理者は VIEW ANY COLUMN MASTER KEY DEFINITION および VIEW ANY COLUMN ENCRYPTION KEY DEFINITION 権限を明示的に付与する必要があります。