Always Encrypted
適用対象: SQL Server Azure SQL データベース Azure SQL Managed Instance
Always Encrypted と セキュリティで保護されたエンクレーブが設定された Always Encrypted は、Azure SQL Database、Azure SQL Managed Instance、および SQL Server データベース内のクレジット カード番号や国または地域の ID 番号 (米国の社会保障番号など) のような機密情報を保護するように設計された機能です。 これにより、クライアントではクライアント アプリケーション内の機密データを暗号化できるようになるため、暗号化キーがデータベース エンジンに公開されることはありません。 この仕組みにより、データを所有し閲覧できるユーザーと、データを管理するがアクセス権を持たないユーザー (オンプレミスのデータベース管理者、クラウド データベース オペレーター、またはその他の高い権限を持つ未承認のユーザー) を分離できます。 結果として、Always Encrypted を使用すると、顧客は機密データをクラウドに安全に格納できるようになり、悪意のある内部関係者によるデータ盗難のリスクが軽減されます。
Always Encrypted には、並べ替え、フィルター処理 (決定論的な暗号化を使用したポイントルックアップを除く) など、暗号化されたデータに対する操作を実行できないといった特定の制限があります。つまり、一部のクエリとアプリケーションは Always Encrypted と互換性がない場合や、アプリケーション ロジックを大幅に変更する必要がある場合があります。
これらの制限に対処するために、セキュリティで保護されたエンクレーブが設定された Always Encrypted では、データベース エンジンがセキュリティで保護されたエンクレーブと呼ばれる保護されたメモリ領域内で暗号化されたデータを処理できる仕組みになっています。 セキュリティで保護されたエンクレーブでは、パターン マッチング、さまざまな比較演算子、およびインプレース暗号化をサポートすることで、Always Encrypted の機密コンピューティング機能が拡張されます。
Always Encrypted を使用すると、アプリケーションの暗号化がシームレスになります。 クライアント側では、Always Encrypted 対応ドライバーが機密データをデータベース エンジンに送信する前に暗号化し、アプリケーション セマンティクスを維持するためにクエリを自動的に書き換えます。 また、暗号化されたデータベース列からクエリ結果を自動的に復号化します。
Always Encrypted の構成
Note
パターン マッチングを実行し、暗号化された列で比較演算子、並べ替え、およびインデックス作成を使用する必要があるアプリケーションの場合は、セキュリティで保護されたエンクレーブが設定された Always Encrypted を実装する必要があります。
このセクションでは、Always Encrypted の設定の概要について説明します。 詳細と概要については、「チュートリアル: Always Encrypted の概要」を参照してください。
データベースで Always Encrypted を構成するには、次の手順に従います。
データを保護するための暗号化キーをプロビジョニングします。 Always Encrypted では 2 種類のキーを使用します。
- 列暗号化キー。
- 列マスター キー。
列暗号化キーは、暗号化された列内のデータを暗号化するために使用されます。 列マスター キーは、1 つ以上の列暗号化キーを暗号化するキー保護キーです。
列マスター キーは、Azure Key Vault、Windows 証明書ストア、ハードウェア セキュリティ モジュールなど、データベース システムの外部の信頼されたキー ストアに保存する必要があります。 その後、列暗号化キーをプロビジョニングし、それぞれを列マスター キーで暗号化する必要があります。
最後に、キーに関するメタデータをデータベースに格納します。 列マスター キーのメタデータには、列マスター キーの場所が含まれています。 列暗号化キーのメタデータには、列暗号化キーの暗号化された値が含まれています。 データベース エンジンは、キーをプレーンテキストで保存したり使用したりしません。
Always Encrypted キーの管理について詳しくは、「Always Encrypted のキー管理の概要」をご覧ください。
機密情報を含む特定のデータベース列に暗号化を設定すると、保護を確実にできます。 これには、暗号化された列を含む新しいテーブルの作成や、既存の列とデータの暗号化が必要になる場合があります。 列の暗号化を構成するときは、暗号化アルゴリズム、データを保護するための列暗号化キー、および暗号化のタイプに関する詳細を指定する必要があります。 Always Encrypted は、次の 2 つのタイプの暗号化をサポートしています。
決定論的な暗号化の場合、任意の指定されたプレーン テキスト値に対して、同じ暗号化された値が常に生成されます。 決定論的な暗号化を使用すると、暗号化された列で、ポイント参照、等価結合、グループ化、およびインデックス作成を行うことができます。 ただし、その結果承認されていないユーザーが、特に True/False や North/South/East/West リージョンなどよくある暗号化された値のセットが小規模である場合は、暗号化された列のパターンを調べることで暗号化された値に関する情報を推測できるようになる可能性もあります。
ランダム化された暗号化では、データを予測できない方法で暗号化する方法が使用されます。 同じプレーンテキストが入力された場合、異なる暗号化された出力が生成されます。 これにより、ランダム化された暗号化のセキュリティが向上します。
暗号化された列に対して比較演算子、並べ替え、およびインデックス作成を使用してパターン マッチングを実行するには、セキュリティで保護されたエンクレーブが設定された Always Encrypted を採用し、ランダム化された暗号化を適用する必要があります。 (セキュリティで保護されたエンクレーブが設定されていない) Always Encrypted のランダム化された暗号化では、暗号化された列での検索、グループ化、インデックス作成、および結合はサポートされません。 代わりに、検索またはグループ化を目的とした列では、決定論的な暗号化を使用することが不可欠です。 これにより、暗号化された列に対するポイント参照、等価結合、グループ化、インデックス作成などの操作が可能になります。
データベース システムは設計上、暗号化キーにアクセスできないため、列の暗号化を行うには、データベースの外部にデータを移動して暗号化する必要があります。 つまり、この暗号化処理には長い時間がかかる可能性があり、ネットワークの中断の影響を受けやすくなります。 さらに、後で列を再暗号化する必要が生じた場合 (暗号化キーのローテーションや暗号化のタイプの変更など) は、同じ問題が再び発生します。 セキュリティで保護されたエンクレーブが設定された Always Encrypted を使用すると、データベースからデータを移動する必要がなくなります。 エンクレーブは信頼されているため、アプリケーション内のクライアント ドライバー、または Azure Data Studio や SQL Server Management Studio (SSMS) などのツールは、暗号化操作中にエンクレーブとキーを安全に共有できます。 その後、エンクレーブが列をその場で暗号化または再暗号化するため、これらのアクションに必要な処理時間を大幅に短縮できます。
Always Encrypted による暗号化アルゴリズムの詳細については、「Always Encrypted による暗号」を参照してください。
SQL ツールを使用して、上記の手順を実行できます。
- SQL Server Management Studio を使用して Always Encrypted キーをプロビジョニングする
- PowerShell を使用した Always Encrypted の構成
- sqlpackage - セットアップ プロセスを自動化する
Always Encrypted キーと保護された機密データが平文でデータベース環境に公開されないようにするため、データベース エンジンはキーのプロビジョニングやデータ暗号化、または復号化操作には関与できません。 そのため、Transact-SQL (T-SQL) では、キーのプロビジョニングや暗号化の操作はサポートされません。 同じ理由で、既存のデータを暗号化するか、(異なる暗号化の種類または列暗号化キーを使用して) 再暗号化する必要があります(SQL ツールはそれを自動化できます)。
暗号化された列の定義を変更した後、sp_refresh_parameter_encryption を実行して、オブジェクトに対する Always Encrypted のメタデータを更新します。
制限事項
暗号化された列に対するクエリには、次の制限事項が適用されます。
ランダム化された暗号化を使用して暗号化された列に対する計算は許可されません。 等価比較に関連する次の操作が、決定論的な暗号化でサポートされています。他の操作は許可されません。
Note
パターン マッチングを実行し、暗号化された列で比較演算子、並べ替え、およびインデックス作成を使用する必要があるアプリケーションの場合は、セキュリティで保護されたエンクレーブが設定された Always Encrypted を実装する必要があります。
プレーンテキストと暗号化されたデータの両方を含む計算をトリガーするクエリ ステートメントは許可されません。 次に例を示します。
- 暗号化された列とプレーンテキスト列またはリテラルを比較します。
- プレーンテキスト列から暗号化された列 (またはその逆の方法で) UPDATE、BULK INSERT、SELECT INTO、または INSERT..SELECT へデータをコピー。
- 暗号化された列へのリテラルの挿入。
このようなステートメントでは、次のようなオペランドの競合エラーが発生します。
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 変数のパラメーター化を適用して、暗号化された列に関連付けられている値を処理するクエリを実行することが不可欠です。 これには、暗号化された列にデータを挿入する、またはフィルターを適用する (決定論的な暗号化が使用される場合) などのシナリオが含まれます。
暗号化された列を対象にしたテーブル値パラメーターはサポートされていません。
次の句を使用するクエリはサポートされていません。
以下の特性を持つ列に対しては、Always Encrypted はサポートされていません。
- 次のデータ型のいずれかを使用する列: xml、timestamp、rowversion、image、ntext、text、sql_variant、hierarchyid、geography、geometry、alias、ユーザー定義型。
- FILESTREAM 列
- IDENTITY プロパティを持つ列
- ROWGUIDCOL プロパティを持つ列
- 決定論的暗号化を使用する場合、バイナリ コード ポイント (_BIN2) 照合順序以外の照合順序を持つ文字列 (varchar、char など) 列。
- ランダム化暗号化を使用する場合、クラスター化インデックスおよび非クラスター化インデックスのキーとなる列 (決定論的な暗号化を使用する列のインデックスがサポートされています)。
- フルテキスト インデックスに含まれる列 (Always Encrypted でフルテキスト検索はサポートされていません)。
- テーブルの計算列を指定します。
- 計算列によって参照される列 (式が Always Encrypted でサポート外の演算を実行するとき)。
- スパース列を使用します。
- ランダム化された暗号化を使用するときに統計によって参照される列 (決定論的な暗号化がサポートされています)。
- パーティション分割列。
- 既定の制約を含む列。
- ランダムな暗号化を使用するときに 一意制約によって参照される列 (明確な暗号化はサポートされます)。
- ランダムな暗号化を使用するときの主キー列 (明確な暗号化はサポートされます)。
- ランダム化された暗号化または明確な暗号化を使用する際の、外部キー制約での列の参照 (参照元および参照先の列が異なるキーまたはアルゴリズムを使用する場合)。
- CHECK 制約によって参照される列。
- 変更データ キャプチャを使用してキャプチャまたは追跡される列。
- Change Tracking を持つテーブル上の主キー列。
- マスキングされている列 (動的データ マスクを使用)。
- ストレッチ データベース テーブル内の列。 (Always Encrypted で暗号化された列を持つテーブルは Stretch で有効にできます)。
重要
拡張データベースは、SQL Server 2022 (16.x) および Azure SQL Database では非推奨になります。 この機能は、データベース エンジンの将来のバージョンで削除される予定です。 新規の開発作業ではこの機能を使用しないようにし、現在この機能を使用しているアプリケーションは修正することを検討してください。
- 外部 (PolyBase) テーブルの列 (注: 外部テーブルと暗号化された列を持つテーブルを同じクエリで使用することはサポートされています)。
次の機能は、暗号化された列では機能しません。
- SQL Server レプリケーション (トランザクション、マージ、またはスナップショット レプリケーション)。 Always On 可用性グループを含む物理レプリケーション機能がサポートされています。
- 分散クエリ (リンク サーバー、OPENROWSET (Transact-SQL)、OPENDATASOURCE (Transact-SQL))。
- 異なるデータベースから暗号化された列に対して結合を実行するデータベース間クエリ。
Always Encrypted Transact-SQL リファレンス
Always Encrypted では、次の Transact-SQL ステートメント、システム カタログ ビュー、システム ストアド プロシージャ、およびアクセス許可が使用されます。
ステートメント
DDL ステートメント | 説明 |
---|---|
CREATE COLUMN MASTER KEY | データベースに列マスター キーのメタデータ オブジェクトを作成します |
DROP COLUMN MASTER KEY | データベースから、列のマスター キーを削除します。 |
CREATE COLUMN ENCRYPTION KEY | 列暗号化キーのメタデータ オブジェクトを作成します。 |
ALTER COLUMN ENCRYPTION KEY | データベースで、暗号化された値を追加または削除する列暗号化キーを変更します。 |
DROP COLUMN ENCRYPTION KEY | 列の暗号化キーをデータベースから削除します。 |
CREATE TABLE (ENCRYPTED WITH) | 列の暗号化を指定します。 |
システム カタログ ビューとストアド プロシージャ
システム カタログ ビューとストアド プロシージャ | 説明 |
---|---|
sys.column_encryption_keys | 列暗号化キー (CEK) に関する情報を返します |
sys.column_encryption_key_values | 列暗号化キー (CEK) の暗号化された値に関する情報を返します |
sys.column_master_keys | 各データベース マスター キーの行を返します |
sp_refresh_parameter_encryption | 指定したスキーマ バインドされていないストアド プロシージャ、ユーザー定義関数、ビュー、DML トリガー、データベース レベルの DDL トリガー、またはサーバー レベルの DDL トリガーのパラメーターの Always Encrypted メタデータを更新します |
sp_describe_parameter_encryption | 指定した Transact-SQL ステートメントとそのパラメーターを分析し、Always Encrypted 機能を使用して保護されているデータベース列に対応するパラメーターを特定します。 |
各列に格納されている暗号化メタデータについては、「sys.columns」も参照してください。
データベース権限
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 | 暗号化された列にクエリを実行するために必要な列暗号化キーのメタデータにアクセスして読み取るために必要です。 |
次の表は、一般的な操作に必要なアクセス許可をまとめたものです。
シナリオ | 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 アクセス許可の両方が、既定で public 固定データベース ロールに付与されます。 データベース管理者は、public ロールに対する アクセス許可を失効 (または拒否) し、そのアクセス許可を特定の役割またはユーザーに付与することで、より制限された制御を実装することができます。
SQL Database では、VIEW ANY COLUMN MASTER KEY DEFINITION および VIEW ANY COLUMN ENCRYPTION KEY DEFINITION 権限は、既定では public 固定データベース ロールには付与されません。 これによって、(旧バージョンの DacFx を使用する) 一部の既存のレガシ ツールが正常に動作するようになります。 暗号化された列を操作するには (暗号化を解除しない場合でも)、データベース管理者は VIEW ANY COLUMN MASTER KEY DEFINITION および VIEW ANY COLUMN ENCRYPTION KEY DEFINITION 権限を明示的に付与する必要があります。