Amazon Web Services ブログ

Amazon RDS for SQL Server におけるAlways Encrypted のセットアップ方法

様々な業界 (ヘルスケア、ライフ サイエンス、金融サービス、小売など) のお客様は、より強力なセキュリティ体制を必要としています。特に、ホストしているデータベースにクレジット カード番号や国民識別番号 (米国の社会保障番号など) などの機密データが含まれている場合、このデータを暗号化してデータベース管理者へのアクセスを制御できるソリューションを提供することが重要になります。 Always Encrypted は、このセキュリティ要件に対する Microsoft SQL Server の機能です。

Always Encrypted を使用すると、クライアントはクライアント アプリケーション内の機密データを暗号化し、暗号化キーをデータベース エンジンに公開することがなくなります。これにより、データを所有し閲覧できるユーザーと、データを管理するがアクセス権を持たないユーザー (データベース管理者、クラウド データベース オペレーター、またはその他の高い権限を持つ未承認ユーザー) が分離されます。その結果、Always Encrypted を使用すると機密データをクラウドに自信を持って保存できるようになり、悪意のある内部関係者によるデータ盗難の可能性を軽減できます。 Always Encrypted はアプリケーションに対して暗号化が透過的に行われます。クライアント コンピューターにインストールする Always Encrypted 対応ドライバーは、クライアント アプリケーション内の機密データを自動的に暗号化および復号化することで透過的なアクセスを実現します。ドライバーは、データをデータベースエンジンに渡す前に機微な情報を保持するカラムのデータを暗号化し、アプリケーションへのセマンティクスが保持されるようにクエリを自動的に書き換えます。同様に、ドライバーはクエリ結果に含まれる暗号化されたデータベースのカラムに保存されたデータを透過的に復号化します。

この投稿では、Windows 証明書ストアを使用して Amazon Relational Database Service (Amazon RDS) for SQL Server インスタンスに Always Encrypted を設定する方法を順番に説明します。 Always Encrypted で使用できる他のキー ストア (Azure Key Vault、ハードウェア セキュリティ モジュール) については、この記事の執筆時点ではサポートされていません。

前提条件

このソリューションをセットアップするには、次のリソースを備えた作業環境が必要です。

  • SQL Server がインストールされた開発ホスト (Always Encrypted 証明書が生成される Windows デバイス)。
  • Windows を実行している Amazon Elastic Compute Cloud (Amazon EC2) でホストされているターゲット アプリケーション サーバー。
  • SQL Server 2016 以降のインスタンス (RDS for SQL Server インスタンス)。
  • 証明書ファイルを保存する Amazon Simple Storage Service (Amazon S3) バケット。
  • Always Encrypted 証明書。

開発マシンで実行されているローカル SQL Server インスタンスを使用して列マスター キーの証明書を生成するには、次の手順を実行します。

  1. SQL Server Management Studio (SSMS) を使用して、暗号化するデータベースのセキュリティ ノードの下にある [列マスター キー] フォルダーを開き、[列マスター キー] フォルダーを右クリックして、[新しい列マスター キー] を選択します。オプションを表示します。
  2. 証明書を「Windows 証明書ストア – 現在のユーザー」 キー ストアに保存します。
  3. Microsoft 管理コンソール (MMC) の [証明書] オプションを使用して、Always Encrypted 証明書を見つけ、サムプリントをメモします (証明書を選択して詳細ダイアログ ボックスを開きます)。このサムプリントは、プロセスを自動化するために開発したスクリプトで必要になります。これまでに証明書スナップインにアクセスしたことがない場合は、ここに記載されている詳細な手順に従ってください。
    • Microsoft 管理コンソール (MMC)を開きます。
    • [ファイル]メニューに移動し、[スナップインの追加または削除]オプションを選択します。
    • リスト化されている利用可能なスナップインから [証明書] オプションを選択します。
    • 個人 / 証明書フォルダに移動します。
    • Always Encrypted 証明書」をダブルクリックします。
    • [詳細] タブを選択し、下にスクロールして、[サムプリント] プロパティを選択します。

  4. 次のダイアログ ボックスが示すように、[ファイルにコピー] を選択して、証明書を PFX ファイルにエクスポートします。
  5. [証明書のエクスポート ウィザード] ダイアログ ボックスで [次へ] を選択します。
  6. はい、秘密キーをエクスポートします」オプションを選択し、[次へ] を選択します。
  7. [Personal Information Exchange (.PFX) 形式] オプションを選択し、[次へ] を選択します。
  8. パスワードを入力し、「AES256-SHA256」暗号化オプションを選択して、[次へ] を選択します。
  9. 適切なパスとファイル名を指定します。 [次へ] を選択します。
  10. [完了] を選択して、証明書のエクスポート プロセスを完了します。
  11. このファイルを指定された S3 バケットにアップロードします。

RDS for SQL Server インスタンスで Always Encrypted を構成する

前提条件となる手順がすべて完了し、Always Encrypted 証明書を PSX ファイルに正常にエクスポートできたら、Amazon RDS for SQL Server インスタンスで Always Encrypted を設定する準備が整います。これを行うには、次の手順を実行します。

  1. Microsoft リモート デスクトップ プロトコル クライアント (RDP) を利用して、ターゲットのアプリケーション サーバー (Windows EC2 クライアント) にリモートで接続します。
  2. Amazon S3 からローカルフォルダーに証明書を含む PSX ファイルをダウンロードします。
  3. 証明書をターゲットとなるアプリケーション サーバーにインポートします。
  4. 以下に示すように、Always Encrypted オプションを有効にして SQL Server Management Studio (SSMS) を使用して Amazon RDS for SQL Server に接続します。
  5. 新しいクエリ ウィンドウを開き、「Enable parameterization for Always Encrypted」にチェックをいれます。
  6. 暗号化されたデータをホストするための新しいデータベースを作成します。
    USE master; 
    GO
    
    IF DB_ID('AlwaysEncrypted') IS NULL
    CREATE DATABASE [AlwaysEncrypted];
    GO
  7. 前に取得した証明書のサムプリントを参照して、列マスター キーを作成します。
    CREATE COLUMN MASTER KEY [AE_ColumnMasterKey]
    WITH
    (
           	KEY_STORE_PROVIDER_NAME = 'MSSQL_CERTIFICATE_STORE',
           	KEY_PATH = 'CurrentUser/My/a619fb0c4029cfcd9d9e935dbb8dc98e0902000f',
    );
    GO
  8. 列暗号化キーを作成します。 1 つのオプションは、SQL Server Management Studio GUI を活用することです。この場合、「Always Encrypted Keys」ノードの下にあるColumn Encryption Keys」フォルダを見つけ、そのフォルダ右クリックして「新しい列暗号化キー」オプションを選択します。列暗号化キーに対する適切な名前を入力し、上で作成した列マスター キーを選択して、[OK] をクリックします。あるいは、以下の T-SQL スクリプトを利用することもできます。次のコードに示されている ENCRYPTED_VALUE を実際に使用している環境の証明書と一致するように調整してください。
    CREATE COLUMN ENCRYPTION KEY [AE_ColumnEncryptionKey]
    WITH VALUES
    (
           	COLUMN_MASTER_KEY = [AE_ColumnMasterKey],
           	ALGORITHM = 'RSA_OAEP',
           	ENCRYPTED_VALUE = 0x016E000001630075007200720065006E00740075007300650072002F006D0079002F006100360031003900660062003000630034003000320039006300660063006400390064003900650039003300350064006200620038006400630039003800650030003900300032003000300030006600374AEE2DA655985A4822614237F61F217171DD13882CE89120BC7B2D5DDD6863668EC2EFE24A64E55ADA2E8A52B0F1E758CD3717157E6612784BB21DE65FDD005322EAA78BC96EA9CB833F5F73E1DD859DB0AE92A6F9D272DEDF53934AF9B43445A01E9FBDBDEF5FCD68087D4EDE85D7479F2BE3D21E401CEABBC6630C004BE1A4BD29BBE2167850F2A08F688BD4AA430F73959D934B44412C62E8EE63D2949B31A1AA07EC80248E1351CF53F5E0C94A142FBE05817A2DEBA87E191B158A748F8925854E52EEBC5D0D620C9BE9BB8157880105A2108F4409B30EE8E8FBF5B51B8C2A884F69B08C568709176A8F9DC1C56E005363BFB2E8E0C5FB27C17551A447E5626432546249839A5AAF334371004BD105F553F5FFCB138C83B4AF54F62163FC08825365B11B0888AF1DB2487C41FBFFE6138C0091500C2B3AD5D3326D36504F5D00C1725C4418263C8D2943BF1DD93B0454DF952975AB795191CF309154B7B6430E55725BF1FC0529C3617B3D44B4A25B983C75339ED999C0143137BB728EB0ACD2878C1DB5780513F456AA50334913931F777297B2EFA42DC5916CCD4F01D05D25F654E65058DED9BF45BE712036AD57A627A8011B14B6406B4C5459C8A7A41D92957C364997FFFDC016A0A64923B1F5794819186443D891F5C534805FDF12EFFF65BCC60FBD4757D9F06E7727C50FE3F5EF440B80292E3AB7536CF09D98
    );
    GO
  9. 暗号化が適切に設定されていることを確認します (参照用にサンプル出力が含まれています)。
    USE [AlwaysEncrypted];
    GO
    
    select * from sys.column_master_keys;
    select * from sys.column_encryption_keys;
    select * from sys.column_encryption_key_values;
    GO

  10. 暗号化された列を含むテーブルを作成します。次のサンプルには、列暗号化キーの両方のオプション (DETERMINISTICとRANDOMIZE) が含まれています。一般に最も使用されるオプションは、非常に高速であるためDETERMINISTICですが、使用例によっては、RANDOMIZEの方が優れたオプションです (列のカーディナリティが非常に低い場合など)。以下の T-SQL ステートメントでは、文字列項目に対するDETERMINISTIC暗号化オプションにはバイナリ コード ポイント照合 (_BIN2) が必要であることに注意することが重要です。
    IF OBJECT_ID('dbo.CustomerInfo', 'U') IS NOT NULL
        DROP TABLE dbo.CustomerInfo;
    GO
    
    CREATE TABLE dbo.CustomerInfo
    (
    CustomerId INT IDENTITY(10000,1) NOT NULL PRIMARY KEY,
    CustomerName NVARCHAR(100) COLLATE Latin1_General_BIN2
        ENCRYPTED WITH (
            ENCRYPTION_TYPE = DETERMINISTIC, 
            ALGORITHM = 'AEAD_AES_256_CBC_HMAC_SHA_256', 
            COLUMN_ENCRYPTION_KEY = AE_ColumnEncryptionKey
        ) NOT NULL,
    CustomerPhone NVARCHAR(11) COLLATE Latin1_General_BIN2
        ENCRYPTED WITH (
        ENCRYPTION_TYPE = RANDOMIZED, 
        ALGORITHM = 'AEAD_AES_256_CBC_HMAC_SHA_256', 
        COLUMN_ENCRYPTION_KEY = AE_ColumnEncryptionKey
        ) NOT NULL
    );
    GO
  11. 最近作成したテーブルをクエリします
    SELECT TOP 3 * FROM dbo.CustomerInfo WITH(NOLOCK);
    GO
  12. いくつかのレコードを挿入します。このサンプルでは、挿入操作を単一のステートメントとして保持することが重要です。そうしないと、SSMS がエラーをスローします。
    DECLARE @CName AS nvarchar(100) = 'CustomerA', @CPhone AS nvarchar(11) = '12123330988'; INSERT INTO [dbo].[CustomerInfo] VALUES (@CName, @CPhone);
    GO
    
    DECLARE @CName AS nvarchar(100) = 'CustomerB', @CPhone AS nvarchar(11) = '14152220786'; INSERT INTO [dbo].[CustomerInfo] VALUES (@CName, @CPhone);
    GO
    
    DECLARE @CName AS nvarchar(100) = 'CustomerC', @CPhone AS nvarchar(11) = '19255550484'; INSERT INTO [dbo].[CustomerInfo] VALUES (@CName, @CPhone);
    GO
  13. 再度、テーブルをクエリします。
    SELECT TOP 3 * FROM dbo.CustomerInfo WITH(NOLOCK);
    GO

値は暗号化されていないことに注意してください。証明書がデプロイされていない他のクライアントからこのクエリを実行すると、暗号化された値のみが表示されます。考えられるテストは、クライアントから証明書を削除してからクエリを再度実行することです。

結論

この投稿では、Windows 証明書ストアを使用して Amazon RDS for SQL Server インスタンスに Always Encrypted を設定する方法を説明しました。 Microsoft SQL Server Always Encrypted は多くの制限付きでリリースされており、Amazon RDS for SQL Server インスタンスでこの機能をセットアップした後も制限は引き続き適用されることに留意することが重要です。この投稿に含まれる手順に従って作成されたリソースを使用する必要がない場合は、環境をクリーンアップすることを忘れないでください。演習中に作成された Amazon RDS for SQL Server インスタンスを削除し、PSX のホストに使用された Amazon S3 バケットを削除します。証明書ファイルを削除し、ターゲット アプリケーション サーバー (Always Encrypted Client) として使用されている Amazon EC2 インスタンスを終了します。

ご質問、コメント、フィードバックがありましたら、この投稿のコメントセクションに残してください。


About the authors

Camilo Leon は、データベースを専門とする AWS のプリンシパル ソリューション アーキテクトであり、カリフォルニア州サンフランシスコを拠点としています。彼は AWS の顧客と協力して、AWS リレーショナル データベースのワークロードとビジネス アプリケーションの設計、デプロイ、管理に対するアーキテクチャのガイダンスと技術サポートを提供しています。余暇には、マウンテン バイク、写真、映画を楽しんでいます。

 

翻訳はソリューションアーキテクトの Yoshinori Sawada が担当しました。原文はこちらです。