Always Encrypted: Azure Key Vault 内で機密データを保護し、暗号化キーを格納するAlways Encrypted: Protect sensitive data and store encryption keys in Azure Key Vault

この記事では、SQL Server Management Studio (SSMS)Always Encrypted ウィザードでデータ暗号化を使用して SQL Database の機密データを保護する方法について説明します。This article shows you how to secure sensitive data in a SQL database with data encryption using the Always Encrypted Wizard in SQL Server Management Studio (SSMS). さらに、Azure Key Vault に各暗号化キーを格納する方法を示す手順についても説明します。It also includes instructions that will show you how to store each encryption key in Azure Key Vault.

Always Encrypted は Azure SQL Database と SQL Server の新しいデータ暗号化テクノロジで、サーバーでの保存時、クライアント/サーバー間の移動中、およびデータの使用中も機密データを保護することができます。Always Encrypted is a new data encryption technology in Azure SQL Database and SQL Server that helps protect sensitive data at rest on the server, during movement between client and server, and while the data is in use. Always Encrypted により、データベース システム内で機密データがプレーンテキストとして表示されることはありません。Always Encrypted ensures that sensitive data never appears as plaintext inside the database system. データ暗号化の構成後に、プレーンテキスト データにアクセスできるのは、キーへのアクセス権を持つクライアント アプリケーションまたはアプリケーション サーバーだけです。After you configure data encryption, only client applications or app servers that have access to the keys can access plaintext data. 詳細については、 Always Encrypted (データベース エンジン) に関するページを参照してください。For detailed information, see Always Encrypted (Database Engine).

Always Encrypted を使用するようデータベースを構成したら、Visual Studio を使って、暗号化されたデータを扱う C# クライアント アプリケーションを作成します。After you configure the database to use Always Encrypted, you will create a client application in C# with Visual Studio to work with the encrypted data.

この記事の手順に従って、Azure SQL データベースに Always Encrypted を設定する方法を学習しましょう。Follow the steps in this article and learn how to set up Always Encrypted for an Azure SQL database. この記事では、次のタスクを実行する方法を説明します。In this article you will learn how to perform the following tasks:

前提条件Prerequisites

注意

この記事は、新しい Azure PowerShell Az モジュールを使用するために更新されました。This article has been updated to use the new Azure PowerShell Az module. AzureRM モジュールはまだ使用でき、少なくとも 2020 年 12 月までは引き続きバグ修正が行われます。You can still use the AzureRM module, which will continue to receive bug fixes until at least December 2020. Az モジュールと AzureRM の互換性の詳細については、「Introducing the new Azure PowerShell Az module (新しい Azure PowerShell Az モジュールの概要)」を参照してください。To learn more about the new Az module and AzureRM compatibility, see Introducing the new Azure PowerShell Az module. Az モジュールのインストール手順については、Azure PowerShell のインストールを参照してください。For Az module installation instructions, see Install Azure PowerShell.

重要

PowerShell Azure Resource Manager モジュールは Azure SQL Database で引き続きサポートされますが、今後の開発はすべて Az.Sql モジュールを対象に行われます。The PowerShell Azure Resource Manager module is still supported by Azure SQL Database, but all future development is for the Az.Sql module. これらのコマンドレットについては、「AzureRM.Sql」を参照してください。For these cmdlets, see AzureRM.Sql. Az モジュールと AzureRm モジュールのコマンドの引数は実質的に同じです。The arguments for the commands in the Az module and in the AzureRm modules are substantially identical.

このチュートリアルには次のものが必要です。For this tutorial, you'll need:

クライアント アプリケーションから SQL Database サービスにアクセスできるようにするEnable your client application to access the SQL Database service

Azure Active Directory (AAD) アプリケーションを設定し、アプリケーションを認証するために必要な "アプリケーション ID" と "キー" をコピーして、クライアント アプリケーションから SQL Database サービスにアクセスできるようにする必要があります。You must enable your client application to access the SQL Database service by setting up an Azure Active Directory (AAD) application and copying the Application ID and key that you will need to authenticate your application.

"アプリケーション ID" と "キー" を取得するには、リソースにアクセスできる Azure Active Directory アプリケーションとサービス プリンシパルの作成に関するページの手順に従ってください。To get the Application ID and key, follow the steps in create an Azure Active Directory application and service principal that can access resources.

キーを格納する Key Vault を作成するCreate a key vault to store your keys

これで、クライアント アプリの構成が完了したので、アプリケーション ID の Key Vault を作成し、ユーザーおよびアプリケーションが資格情報コンテナーの機密情報 (Always Encrypted キー) にアクセスすることを許可するアクセス ポリシーを構成できます。Now that your client app is configured and you have your application ID, it's time to create a key vault and configure its access policy so you and your application can access the vault's secrets (the Always Encrypted keys). 新しい列のマスター キーを作成したり、SQL Server Management Studio で暗号化を設定したりするには、create get list sign verify wrapKey、および unwrapKey 権限が必要です。The create, get, list, sign, verify, wrapKey, and unwrapKey permissions are required for creating a new column master key and for setting up encryption with SQL Server Management Studio.

次のスクリプトを実行して、Key Vault をすばやく作成できます。You can quickly create a key vault by running the following script. これらのコマンドレットの詳細、および Key Vault の作成と構成の詳細については、「Azure Key Vault とは」をご覧ください。For a detailed explanation of these cmdlets and more information about creating and configuring a key vault, see What is Azure Key Vault?.

    $subscriptionName = '<your Azure subscription name>'
    $userPrincipalName = '<username@domain.com>'
    $applicationId = '<application ID from your AAD application>'
    $resourceGroupName = '<resource group name>'
    # Use the same resource group name when creating your SQL Database below
    $location = '<datacenter location>'
    $vaultName = 'AeKeyVault'


    Connect-AzAccount
    $subscriptionId = (Get-AzSubscription -SubscriptionName $subscriptionName).Id
    Set-AzContext -SubscriptionId $subscriptionId

    New-AzResourceGroup -Name $resourceGroupName -Location $location
    New-AzKeyVault -VaultName $vaultName -ResourceGroupName $resourceGroupName -Location $location

    Set-AzKeyVaultAccessPolicy -VaultName $vaultName -ResourceGroupName $resourceGroupName -PermissionsToKeys create,get,wrapKey,unwrapKey,sign,verify,list -UserPrincipalName $userPrincipalName
    Set-AzKeyVaultAccessPolicy  -VaultName $vaultName  -ResourceGroupName $resourceGroupName -ServicePrincipalName $applicationId -PermissionsToKeys get,wrapKey,unwrapKey,sign,verify,list

空の SQL データベースを作成するCreate a blank SQL database

  1. Azure Portal にサインインします。Sign in to the Azure portal.

  2. [リソースの作成] > [データベース] > [SQL データベース] に移動します。Go to Create a resource > Databases > SQL Database.

  3. 新規または既存のサーバーに Clinic という名前の空のデータベースを作成します。Create a Blank database named Clinic on a new or existing server. Azure Portal でデータベースを作成する詳しい手順については、「初めての Azure SQL データベース」を参照してください。For detailed directions about how to create a database in the Azure portal, see Your first Azure SQL database.

    空のデータベースの作成

チュートリアルの後の方で接続文字列が必要になるため、データベースを作成した後に、新しい Clinic データベースを参照し、接続文字列をコピーします。You will need the connection string later in the tutorial, so after you create the database, browse to the new Clinic database and copy the connection string. いつでも接続文字列を取得できますが、Azure ポータルで簡単にそれをコピーできます。You can get the connection string at any time, but it's easy to copy it in the Azure portal.

  1. [SQL Database] > [Clinic] > [データベース接続文字列の表示] の順に移動します。Go to SQL databases > Clinic > Show database connection strings.

  2. ADO.NETの接続文字列をコピーします。Copy the connection string for ADO.NET.

    接続文字列のコピー

SSMS を使用してデータベースに接続するConnect to the database with SSMS

SSMS を開き、Clinic データベースを作成したサーバーに接続します。Open SSMS and connect to the server with the Clinic database.

  1. SSMS を開きます。Open SSMS. ( [サーバーへの接続] ウィンドウを開いていない場合は、 [接続] > [データベース エンジン] の順に移動して開きます)。(Go to Connect > Database Engine to open the Connect to Server window if it isn't open.)

  2. サーバー名と資格情報を入力します。Enter your server name and credentials. サーバー名がわからない場合は、[SQL Database] ブレードか、先ほどコピーした接続文字列で確認できます。The server name can be found on the SQL database blade and in the connection string you copied earlier. database.windows.netを含む完全なサーバー名を入力してください。Type the complete server name, including database.windows.net.

    接続文字列のコピー

[新しいファイアウォール規則] ウィンドウが表示された場合は、Azure にサインインして、SSMS で自動的に新しいファイアウォール規則を作成します。If the New Firewall Rule window opens, sign in to Azure and let SSMS create a new firewall rule for you.

テーブルを作成するCreate a table

このセクションでは、患者データを保持するテーブルを作成します。In this section, you will create a table to hold patient data. これは最初は通常のテーブルで、次のセクションで暗号化を構成します。It's not initially encrypted--you will configure encryption in the next section.

  1. [データベース] を展開します。Expand Databases.
  2. Clinic データベースを右クリックして、 [新しいクエリ] をクリックします。Right-click the Clinic database and click New Query.
  3. [新しいクエリ] ウィンドウに次の Transact-SQL (T-SQL) を貼り付けて、 実行 します。Paste the following Transact-SQL (T-SQL) into the new query window and Execute it.
        CREATE TABLE [dbo].[Patients](
         [PatientId] [int] IDENTITY(1,1),
         [SSN] [char](11) NOT NULL,
         [FirstName] [nvarchar](50) NULL,
         [LastName] [nvarchar](50) NULL,
         [MiddleName] [nvarchar](50) NULL,
         [StreetAddress] [nvarchar](50) NULL,
         [City] [nvarchar](50) NULL,
         [ZipCode] [char](5) NULL,
         [State] [char](2) NULL,
         [BirthDate] [date] NOT NULL
         PRIMARY KEY CLUSTERED ([PatientId] ASC) ON [PRIMARY] );
         GO

列を暗号化する (Always Encrypted を構成する)Encrypt columns (configure Always Encrypted)

SSMS に用意されているウィザードを使用すると、列マスター キー、列暗号化キー、および暗号化する列を設定するだけで簡単に Always Encrypted を構成できます。SSMS provides a wizard that helps you easily configure Always Encrypted by setting up the column master key, column encryption key, and encrypted columns for you.

  1. [データベース] > 空の > [テーブル] を使用して、SQL データベース内の機密データを保護する方法について説明します。Expand Databases > Clinic > Tables.

  2. Patients テーブルを右クリックして [列の暗号化] を選択すると、Always Encrypted ウィザードが起動します。Right-click the Patients table and select Encrypt Columns to open the Always Encrypted wizard:

    [列の暗号化]

Always Encrypted ウィザードには、 [列の選択][マスター キー構成][検証] 、および [まとめ] のセクションがあります。The Always Encrypted wizard includes the following sections: Column Selection, Master Key Configuration, Validation, and Summary.

列の選択Column Selection

[説明] ページの [次へ] をクリックして、 [列の選択] ページを開きます。Click Next on the Introduction page to open the Column Selection page. このページで、暗号化する列、 暗号化の種類、使用する列暗号化キー (CEK) を選択します。On this page, you will select which columns you want to encrypt, the type of encryption, and what column encryption key (CEK) to use.

各患者の SSNBirthDate 情報を暗号化します。Encrypt SSN and BirthDate information for each patient. SSN 列では決定論的な暗号化を使用します。この場合、等値のルックアップ、結合、グループ化を実行できます。The SSN column will use deterministic encryption, which supports equality lookups, joins, and group by. BirthDate 列ではランダム化された暗号化を使用します。この場合、操作は実行できません。The BirthDate column will use randomized encryption, which does not support operations.

[暗号化の種類] として、SSN 列には [決定論的] を、BirthDate 列には [ランダム化] を選択します。Set the Encryption Type for the SSN column to Deterministic and the BirthDate column to Randomized. [次へ] をクリックします。Click Next.

[列の暗号化]

マスター キー構成Master Key Configuration

[マスター キーの構成] ページでは、CMK を設定し、その CMK を格納するキー ストア プロバイダーを選択します。The Master Key Configuration page is where you set up your CMK and select the key store provider where the CMK will be stored. 現時点では、Windows 証明書ストア、Azure Key Vault、またはハードウェア セキュリティ モジュール (HSM) に格納できます。Currently, you can store a CMK in the Windows certificate store, Azure Key Vault, or a hardware security module (HSM).

このチュートリアルでは、Azure Key Vault にキーを格納する方法を説明します。This tutorial shows how to store your keys in Azure Key Vault.

  1. [Azure Key Vault] を選択します。Select Azure Key Vault.
  2. ドロップダウン リストから必要な Key Vault を選択します。Select the desired key vault from the drop-down list.
  3. [次へ] をクリックします。Click Next.

マスター キー構成

検証Validation

列の暗号化はすぐに実行することも、PowerShell スクリプトを保存して後から実行することもできます。You can encrypt the columns now or save a PowerShell script to run later. このチュートリアルでは、 [今すぐ続行して完了] を選択して [次へ] をクリックします。For this tutorial, select Proceed to finish now and click Next.

まとめSummary

設定がすべて正しいことを確認し、 [完了] をクリックすれば、Always Encrypted の設定は完了です。Verify that the settings are all correct and click Finish to complete the setup for Always Encrypted.

まとめ

ウィザードのアクションの確認Verify the wizard's actions

ウィザードが完了すると、データベースに Always Encrypted が設定されています。After the wizard is finished, your database is set up for Always Encrypted. ウィザードでは、次の操作が実行されました。The wizard performed the following actions:

  • 列マスター キーを作成し、Azure Key Vault に格納しました。Created a column master key and stored it in Azure Key Vault.
  • 列暗号化キーを作成し、Azure Key Vault に格納しました。Created a column encryption key and stored it in Azure Key Vault.
  • 選択した列の暗号化の構成Configured the selected columns for encryption. Patients テーブルにはまだデータがありませんが、選択した列にデータが存在していれば、この段階で暗号化されています。The Patients table currently has no data, but any existing data in the selected columns is now encrypted.

SSMS でキーが生成されていることを確認するには、 [Clinic] > [セキュリティ] > [Always Encrypted キー] の順に展開します。You can verify the creation of the keys in SSMS by expanding Clinic > Security > Always Encrypted Keys.

暗号化されたデータを扱うクライアント アプリケーションを作成するCreate a client application that works with the encrypted data

Always Encrypted を設定したので、暗号化された列に対して、insertsselects を実行するアプリケーションを構築できます。Now that Always Encrypted is set up, you can build an application that performs inserts and selects on the encrypted columns.

重要

Always Encrypted 列を構成したサーバーにプレーンテキスト データを渡す場合は、 SqlParameter オブジェクトを使用する必要があります。Your application must use SqlParameter objects when passing plaintext data to the server with Always Encrypted columns. SqlParameter オブジェクトを使用せずにリテラル値を渡すと、例外が発生します。Passing literal values without using SqlParameter objects will result in an exception.

  1. Visual Studio を開き、新しい C# コンソール アプリケーション (Visual Studio 2015 以前) または コンソール アプリケーション (.NET Framework) (Visual Studio 2017 以降) を作成します。Open Visual Studio and create a new C# Console Application (Visual Studio 2015 and earlier) or Console App (.NET Framework) (Visual Studio 2017 and later). プロジェクトは必ず .NET Framework 4.6 以降に設定してください。Make sure your project is set to .NET Framework 4.6 or later.
  2. プロジェクトに AlwaysEncryptedConsoleAKVApp という名前を付けて、 [OK] をクリックします。Name the project AlwaysEncryptedConsoleAKVApp and click OK.
  3. [ツール] > [NuGet パッケージ マネージャー] > [パッケージ マネージャー コンソール] の順に進んで、次の NuGet のパッケージをインストールします。Install the following NuGet packages by going to Tools > NuGet Package Manager > Package Manager Console.

パッケージ マネージャー コンソールで、次の 2 行のコードを実行します。Run these two lines of code in the Package Manager Console.

    Install-Package Microsoft.SqlServer.Management.AlwaysEncrypted.AzureKeyVaultProvider
    Install-Package Microsoft.IdentityModel.Clients.ActiveDirectory

接続文字列を変更して Always Encrypted を有効にするModify your connection string to enable Always Encrypted

このセクションでは、データベース接続文字列で Always Encrypted を有効にする方法を説明します。This section explains how to enable Always Encrypted in your database connection string.

Always Encrypted を有効にするには、接続文字列に Column Encryption Setting キーワードを追加し、Enabled に設定します。To enable Always Encrypted, you need to add the Column Encryption Setting keyword to your connection string and set it to Enabled.

接続文字列で直接設定することも、 SqlConnectionStringBuilderを使用して設定することもできます。You can set this directly in the connection string, or you can set it by using SqlConnectionStringBuilder. SqlConnectionStringBuilderを使用する方法については、次のセクションでサンプル アプリケーションを使って説明します。The sample application in the next section shows how to use SqlConnectionStringBuilder.

接続文字列で Always Encrypted を有効にするEnable Always Encrypted in the connection string

接続文字列に次のキーワードを追加します。Add the following keyword to your connection string.

Column Encryption Setting=Enabled

SqlConnectionStringBuilder を使って Always Encrypted を有効にするEnable Always Encrypted with SqlConnectionStringBuilder

次のコードは、SqlConnectionStringBuilder.ColumnEncryptionSettingEnabled に設定して Always Encrypted を有効にする方法を示しています。The following code shows how to enable Always Encrypted by setting SqlConnectionStringBuilder.ColumnEncryptionSetting to Enabled.

    // Instantiate a SqlConnectionStringBuilder.
    SqlConnectionStringBuilder connStringBuilder =
       new SqlConnectionStringBuilder("replace with your connection string");

    // Enable Always Encrypted.
    connStringBuilder.ColumnEncryptionSetting =
       SqlConnectionColumnEncryptionSetting.Enabled;

Azure Key Vault プロバイダーを登録するRegister the Azure Key Vault provider

次のコードは、Azure Key Vault プロバイダーを ADO.NET ドライバーに登録する方法を示しています。The following code shows how to register the Azure Key Vault provider with the ADO.NET driver.

    private static ClientCredential _clientCredential;

    static void InitializeAzureKeyVaultProvider()
    {
       _clientCredential = new ClientCredential(applicationId, clientKey);

       SqlColumnEncryptionAzureKeyVaultProvider azureKeyVaultProvider =
          new SqlColumnEncryptionAzureKeyVaultProvider(GetToken);

       Dictionary<string, SqlColumnEncryptionKeyStoreProvider> providers =
          new Dictionary<string, SqlColumnEncryptionKeyStoreProvider>();

       providers.Add(SqlColumnEncryptionAzureKeyVaultProvider.ProviderName, azureKeyVaultProvider);
       SqlConnection.RegisterColumnEncryptionKeyStoreProviders(providers);
    }

Always Encrypted サンプル コンソール アプリケーションAlways Encrypted sample console application

このサンプルでは次の操作を行います。This sample demonstrates how to:

  • 接続文字列を変更して Always Encrypted を有効にする。Modify your connection string to enable Always Encrypted.
  • アプリケーションのキー ストア プロバイダーとして、Azure Key Vault を登録します。Register Azure Key Vault as the application's key store provider.
  • 暗号化された列にデータを挿入する。Insert data into the encrypted columns.
  • 暗号化された列をフィルター処理して、特定の値を持つレコードを選択する。Select a record by filtering for a specific value in an encrypted column.

Program.cs の内容を次のコードに置き換えます。Replace the contents of Program.cs with the following code. Main メソッドのすぐ前の行にある connectionString のグローバル変数の接続文字列を、Azure ポータルから取得した有効な接続文字列に置き換えます。Replace the connection string for the global connectionString variable in the line that directly precedes the Main method with your valid connection string from the Azure portal. コードに対する変更はこれだけです。This is the only change you need to make to this code.

アプリケーションを実行して、Always Encrypted の動作を見てみましょう。Run the app to see Always Encrypted in action.

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Threading.Tasks;
    using System.Data;
    using System.Data.SqlClient;
    using Microsoft.IdentityModel.Clients.ActiveDirectory;
    using Microsoft.SqlServer.Management.AlwaysEncrypted.AzureKeyVaultProvider;

    namespace AlwaysEncryptedConsoleAKVApp
    {
    class Program
    {
        // Update this line with your Clinic database connection string from the Azure portal.
        static string connectionString = @"<connection string from the portal>";
        static string applicationId = @"<application ID from your AAD application>";
        static string clientKey = "<key from your AAD application>";


        static void Main(string[] args)
        {
            InitializeAzureKeyVaultProvider();

            Console.WriteLine("Signed in as: " + _clientCredential.ClientId);

            Console.WriteLine("Original connection string copied from the Azure portal:");
            Console.WriteLine(connectionString);

            // Create a SqlConnectionStringBuilder.
            SqlConnectionStringBuilder connStringBuilder =
                new SqlConnectionStringBuilder(connectionString);

            // Enable Always Encrypted for the connection.
            // This is the only change specific to Always Encrypted
            connStringBuilder.ColumnEncryptionSetting =
                SqlConnectionColumnEncryptionSetting.Enabled;

            Console.WriteLine(Environment.NewLine + "Updated connection string with Always Encrypted enabled:");
            Console.WriteLine(connStringBuilder.ConnectionString);

            // Update the connection string with a password supplied at runtime.
            Console.WriteLine(Environment.NewLine + "Enter server password:");
            connStringBuilder.Password = Console.ReadLine();


            // Assign the updated connection string to our global variable.
            connectionString = connStringBuilder.ConnectionString;


            // Delete all records to restart this demo app.
            ResetPatientsTable();

            // Add sample data to the Patients table.
            Console.Write(Environment.NewLine + "Adding sample patient data to the database...");

            InsertPatient(new Patient()
            {
                SSN = "999-99-0001",
                FirstName = "Orlando",
                LastName = "Gee",
                BirthDate = DateTime.Parse("01/04/1964")
            });
            InsertPatient(new Patient()
            {
                SSN = "999-99-0002",
                FirstName = "Keith",
                LastName = "Harris",
                BirthDate = DateTime.Parse("06/20/1977")
            });
            InsertPatient(new Patient()
            {
                SSN = "999-99-0003",
                FirstName = "Donna",
                LastName = "Carreras",
                BirthDate = DateTime.Parse("02/09/1973")
            });
            InsertPatient(new Patient()
            {
                SSN = "999-99-0004",
                FirstName = "Janet",
                LastName = "Gates",
                BirthDate = DateTime.Parse("08/31/1985")
            });
            InsertPatient(new Patient()
            {
                SSN = "999-99-0005",
                FirstName = "Lucy",
                LastName = "Harrington",
                BirthDate = DateTime.Parse("05/06/1993")
            });


            // Fetch and display all patients.
            Console.WriteLine(Environment.NewLine + "All the records currently in the Patients table:");

            foreach (Patient patient in SelectAllPatients())
            {
                Console.WriteLine(patient.FirstName + " " + patient.LastName + "\tSSN: " + patient.SSN + "\tBirthdate: " + patient.BirthDate);
            }

            // Get patients by SSN.
            Console.WriteLine(Environment.NewLine + "Now lets locate records by searching the encrypted SSN column.");

            string ssn;

            // This very simple validation only checks that the user entered 11 characters.
            // In production be sure to check all user input and use the best validation for your specific application.
            do
            {
                Console.WriteLine("Please enter a valid SSN (ex. 999-99-0003):");
                ssn = Console.ReadLine();
            } while (ssn.Length != 11);

            // The example allows duplicate SSN entries so we will return all records
            // that match the provided value and store the results in selectedPatients.
            Patient selectedPatient = SelectPatientBySSN(ssn);

            // Check if any records were returned and display our query results.
            if (selectedPatient != null)
            {
                Console.WriteLine("Patient found with SSN = " + ssn);
                Console.WriteLine(selectedPatient.FirstName + " " + selectedPatient.LastName + "\tSSN: "
                    + selectedPatient.SSN + "\tBirthdate: " + selectedPatient.BirthDate);
            }
            else
            {
                Console.WriteLine("No patients found with SSN = " + ssn);
            }

            Console.WriteLine("Press Enter to exit...");
            Console.ReadLine();
        }


        private static ClientCredential _clientCredential;

        static void InitializeAzureKeyVaultProvider()
        {

            _clientCredential = new ClientCredential(applicationId, clientKey);

            SqlColumnEncryptionAzureKeyVaultProvider azureKeyVaultProvider =
              new SqlColumnEncryptionAzureKeyVaultProvider(GetToken);

            Dictionary<string, SqlColumnEncryptionKeyStoreProvider> providers =
              new Dictionary<string, SqlColumnEncryptionKeyStoreProvider>();

            providers.Add(SqlColumnEncryptionAzureKeyVaultProvider.ProviderName, azureKeyVaultProvider);
            SqlConnection.RegisterColumnEncryptionKeyStoreProviders(providers);
        }

        public async static Task<string> GetToken(string authority, string resource, string scope)
        {
            var authContext = new AuthenticationContext(authority);
            AuthenticationResult result = await authContext.AcquireTokenAsync(resource, _clientCredential);

            if (result == null)
                throw new InvalidOperationException("Failed to obtain the access token");
            return result.AccessToken;
        }

        static int InsertPatient(Patient newPatient)
        {
            int returnValue = 0;

            string sqlCmdText = @"INSERT INTO [dbo].[Patients] ([SSN], [FirstName], [LastName], [BirthDate])
     VALUES (@SSN, @FirstName, @LastName, @BirthDate);";

            SqlCommand sqlCmd = new SqlCommand(sqlCmdText);


            SqlParameter paramSSN = new SqlParameter(@"@SSN", newPatient.SSN);
            paramSSN.DbType = DbType.AnsiStringFixedLength;
            paramSSN.Direction = ParameterDirection.Input;
            paramSSN.Size = 11;

            SqlParameter paramFirstName = new SqlParameter(@"@FirstName", newPatient.FirstName);
            paramFirstName.DbType = DbType.String;
            paramFirstName.Direction = ParameterDirection.Input;

            SqlParameter paramLastName = new SqlParameter(@"@LastName", newPatient.LastName);
            paramLastName.DbType = DbType.String;
            paramLastName.Direction = ParameterDirection.Input;

            SqlParameter paramBirthDate = new SqlParameter(@"@BirthDate", newPatient.BirthDate);
            paramBirthDate.SqlDbType = SqlDbType.Date;
            paramBirthDate.Direction = ParameterDirection.Input;

            sqlCmd.Parameters.Add(paramSSN);
            sqlCmd.Parameters.Add(paramFirstName);
            sqlCmd.Parameters.Add(paramLastName);
            sqlCmd.Parameters.Add(paramBirthDate);

            using (sqlCmd.Connection = new SqlConnection(connectionString))
            {
                try
                {
                    sqlCmd.Connection.Open();
                    sqlCmd.ExecuteNonQuery();
                }
                catch (Exception ex)
                {
                    returnValue = 1;
                    Console.WriteLine("The following error was encountered: ");
                    Console.WriteLine(ex.Message);
                    Console.WriteLine(Environment.NewLine + "Press Enter key to exit");
                    Console.ReadLine();
                    Environment.Exit(0);
                }
            }
            return returnValue;
        }


        static List<Patient> SelectAllPatients()
        {
            List<Patient> patients = new List<Patient>();


            SqlCommand sqlCmd = new SqlCommand(
              "SELECT [SSN], [FirstName], [LastName], [BirthDate] FROM [dbo].[Patients]",
                new SqlConnection(connectionString));


            using (sqlCmd.Connection = new SqlConnection(connectionString))

            using (sqlCmd.Connection = new SqlConnection(connectionString))
            {
                try
                {
                    sqlCmd.Connection.Open();
                    SqlDataReader reader = sqlCmd.ExecuteReader();

                    if (reader.HasRows)
                    {
                        while (reader.Read())
                        {
                            patients.Add(new Patient()
                            {
                                SSN = reader[0].ToString(),
                                FirstName = reader[1].ToString(),
                                LastName = reader["LastName"].ToString(),
                                BirthDate = (DateTime)reader["BirthDate"]
                            });
                        }
                    }
                }
                catch (Exception ex)
                {
                    throw;
                }
            }

            return patients;
        }


        static Patient SelectPatientBySSN(string ssn)
        {
            Patient patient = new Patient();

            SqlCommand sqlCmd = new SqlCommand(
                "SELECT [SSN], [FirstName], [LastName], [BirthDate] FROM [dbo].[Patients] WHERE [SSN]=@SSN",
                new SqlConnection(connectionString));

            SqlParameter paramSSN = new SqlParameter(@"@SSN", ssn);
            paramSSN.DbType = DbType.AnsiStringFixedLength;
            paramSSN.Direction = ParameterDirection.Input;
            paramSSN.Size = 11;

            sqlCmd.Parameters.Add(paramSSN);


            using (sqlCmd.Connection = new SqlConnection(connectionString))
            {
                try
                {
                    sqlCmd.Connection.Open();
                    SqlDataReader reader = sqlCmd.ExecuteReader();

                    if (reader.HasRows)
                    {
                        while (reader.Read())
                        {
                            patient = new Patient()
                            {
                                SSN = reader[0].ToString(),
                                FirstName = reader[1].ToString(),
                                LastName = reader["LastName"].ToString(),
                                BirthDate = (DateTime)reader["BirthDate"]
                            };
                        }
                    }
                    else
                    {
                        patient = null;
                    }
                }
                catch (Exception ex)
                {
                    throw;
                }
            }
            return patient;
        }


        // This method simply deletes all records in the Patients table to reset our demo.
        static int ResetPatientsTable()
        {
            int returnValue = 0;

            SqlCommand sqlCmd = new SqlCommand("DELETE FROM Patients");
            using (sqlCmd.Connection = new SqlConnection(connectionString))
            {
                try
                {
                    sqlCmd.Connection.Open();
                    sqlCmd.ExecuteNonQuery();

                }
                catch (Exception ex)
                {
                    returnValue = 1;
                }
            }
            return returnValue;
        }
    }

    class Patient
    {
        public string SSN { get; set; }
        public string FirstName { get; set; }
        public string LastName { get; set; }
        public DateTime BirthDate { get; set; }
    }
    }

データが暗号化されていることを確認するVerify that the data is encrypted

サーバー上の実際のデータが暗号化されていることを簡単に確認するには、SSMS で Patients データをクエリします ( Column Encryption Setting がまだ有効になっていない現在の接続を使用します)。You can quickly check that the actual data on the server is encrypted by querying the Patients data with SSMS (using your current connection where Column Encryption Setting is not yet enabled).

Clinic データベースで次のクエリを実行します。Run the following query on the Clinic database.

    SELECT FirstName, LastName, SSN, BirthDate FROM Patients;

暗号化された列にプレーンテキスト データが含まれていないことがわかります。You can see that the encrypted columns do not contain any plaintext data.

新しいコンソール アプリケーション

プレーンテキスト データにアクセスする SSMS を使用するには、まず、ユーザーが Azure Key Vault への適切なアクセス許可、getunwrapKey、および verify を持っていることを確認する必要があります。To use SSMS to access the plaintext data, you first need to ensure that the user has proper permissions to the Azure Key Vault: get, unwrapKey, and verify. 詳細については、「列マスター キーを作成して保存する (Always Encrypted)」を参照してください。For detailed information, see Create and Store Column Master Keys (Always Encrypted).

次に、接続中に Column Encryption Setting=enabled パラメーターを追加します。Then add the Column Encryption Setting=enabled parameter during your connection.

  1. SSMS のオブジェクト エクスプローラーでサーバーを右クリックし、 [切断] を選択します。In SSMS, right-click your server in Object Explorer and choose Disconnect.

  2. [接続] > [データベース エンジン] の順にクリックして [サーバーへの接続] ウィンドウを開き、 [オプション] をクリックします。Click Connect > Database Engine to open the Connect to Server window and click Options.

  3. [追加の接続パラメーター] をクリックし、「Column Encryption Setting=enabled」と入力します。Click Additional Connection Parameters and type Column Encryption Setting=enabled.

    新しいコンソール アプリケーション

  4. Clinic データベースで次のクエリを実行します。Run the following query on the Clinic database.

       SELECT FirstName, LastName, SSN, BirthDate FROM Patients;
    

    暗号化された列のプレーンテキスト データを確認できます。You can now see the plaintext data in the encrypted columns. 新しいコンソール アプリケーションNew console application

次の手順Next steps

Always Encrypted を使用するデータベースを作成したら、次の操作を試してみてください。After you create a database that uses Always Encrypted, you may want to do the following: