Always Encrypted: protección de datos confidenciales y almacenamiento de las claves de cifrado en Azure Key VaultAlways Encrypted: Protect sensitive data and store encryption keys in Azure Key Vault

En este artículo se muestra cómo proteger los datos confidenciales de una base de datos SQL con cifrado de datos mediante el asistente de Always Encrypted en SQL Server Management Studio (SSMS).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). También incluye instrucciones para almacenar cada clave de cifrado en Azure Key Vault.It also includes instructions that will show you how to store each encryption key in Azure Key Vault.

Always Encrypted es una nueva tecnología de cifrado de datos de Azure SQL Database y SQL Server que ayuda a proteger los datos confidenciales en reposo en el servidor durante el traslado entre el cliente y el servidor, y mientras los datos están en uso.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 garantiza que los datos confidenciales nunca van a aparecer como texto no cifrado dentro del sistema de base de datos.Always Encrypted ensures that sensitive data never appears as plaintext inside the database system. Después de configurar el cifrado de datos, solo las aplicaciones cliente o los servidores de aplicaciones que tienen acceso a las claves pueden acceder a los datos de texto no cifrado.After you configure data encryption, only client applications or app servers that have access to the keys can access plaintext data. Para más información, consulte Always Encrypted (motor de base de datos).For detailed information, see Always Encrypted (Database Engine).

Después de configurar la base de datos para usar Always Encrypted, creará una aplicación cliente en C# con Visual Studio para trabajar con los datos cifrados.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.

Siga los pasos de este artículo y aprenda a configurar Always Encrypted para una base de datos de Azure SQL.Follow the steps in this article and learn how to set up Always Encrypted for an Azure SQL database. En este artículo aprenderá a realizar las siguientes tareas:In this article you will learn how to perform the following tasks:

Requisitos previosPrerequisites

Para este tutorial, necesitará:For this tutorial, you'll need:

Habilitación de la aplicación cliente para obtener acceso al servicio de SQL DatabaseEnable your client application to access the SQL Database service

Debe habilitar la aplicación cliente para obtener acceso al servicio de SQL Database mediante la configuración de una aplicación de Azure Active Directory (AAD) y la copia del id. de la aplicación y la clave que necesitará para autenticar la aplicación.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.

Para obtener el id. de la aplicación y la clave, siga estos pasos acerca de cómo crear una aplicación de Azure Active Directory y una entidad de servicio con acceso a los recursos.To get the Application ID and key, follow the steps in create an Azure Active Directory application and service principal that can access resources.

Creación de un almacén de claves para guardar las clavesCreate a key vault to store your keys

Ahora que la aplicación cliente está configurada y tiene el id. de la aplicación, es el momento de crear un almacén de claves y configurar su directiva de acceso para que el usuario y su aplicación puedan acceder a los secretos del almacén (las claves de 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). Los permisos create, get, list, sign, verify, wrapKey y unwrapKey son necesarios para crear una nueva clave maestra de columna y configurar el cifrado con SQL Server Management Studio.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.

Para crear rápidamente un almacén de claves, ejecute el script siguiente.You can quickly create a key vault by running the following script. Para obtener una explicación detallada de estos comandos y obtener más información sobre cómo crear y configurar un almacén de claves, consulte ¿Qué es Azure Key Vault?.For a detailed explanation of these commands and more information about creating and configuring a key vault, see What is Azure Key Vault?.

Importante

El módulo de Azure Resource Manager (RM) para PowerShell todavía es compatible con Azure SQL Database, pero todo el desarrollo futuro se realizará para el módulo Az.Sql.The PowerShell Azure Resource Manager (RM) module is still supported by Azure SQL Database, but all future development is for the Az.Sql module. El módulo de AzureRM continuará recibiendo correcciones de errores hasta diciembre de 2020 como mínimo.The AzureRM module will continue to receive bug fixes until at least December 2020. Los argumentos para los comandos del módulo Az y los módulos AzureRm son esencialmente idénticos.The arguments for the commands in the Az module and in the AzureRm modules are substantially identical. Para obtener más información acerca la compatibilidad, vea Presentación del nuevo módulo Az de Azure PowerShell.For more about their compatibility, see Introducing the new Azure PowerShell Az module.

$subscriptionName = '<subscriptionName>'
$userPrincipalName = '<username@domain.com>'
$applicationId = '<applicationId from AAD application>'
$resourceGroupName = '<resourceGroupName>' # use the same resource group name when creating your SQL Database below
$location = '<datacenterLocation>'
$vaultName = '<vaultName>'

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

Crear una instancia en blanco en SQL DatabaseCreate a blank SQL database

  1. Inicie sesión en el Azure Portal.Sign in to the Azure portal.

  2. Vaya a Crear un recurso > Bases de datos > SQL Database.Go to Create a resource > Databases > SQL Database.

  3. Cree una base de datos en blanco denominada Clinic en un servidor nuevo o existente.Create a Blank database named Clinic on a new or existing server. Para obtener instrucciones detalladas para crear una base de datos en Azure Portal, consulte Su primera base de datos de Azure SQL.For detailed directions about how to create a database in the Azure portal, see Your first Azure SQL database.

    Crear una base de datos en blanco

Necesitará la cadena de conexión más adelante en el tutorial; por lo tanto, después de crear la base de datos, vaya a la nueva base de datos Clinic y copie la cadena de conexión.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. Puede obtener la cadena de conexión en cualquier momento, pero es fácil copiarla en el Portal de Azure.You can get the connection string at any time, but it's easy to copy it in the Azure portal.

  1. Vaya a Bases de datos SQL > Clinic > Mostrar las cadenas de conexión de la base de datos.Go to SQL databases > Clinic > Show database connection strings.

  2. Copie la cadena de conexión para ADO.NET.Copy the connection string for ADO.NET.

    Copiar la cadena de conexión

Conéctese a la base de datos con SSMSConnect to the database with SSMS

Abra SSMS y conéctese al servidor con la base de datos Clinic.Open SSMS and connect to the server with the Clinic database.

  1. Abra SSMS.Open SSMS. (Vaya a Conectar > Motor de base de datos para abrir la ventana Conectar con el servidor si no está abierta).(Go to Connect > Database Engine to open the Connect to Server window if it isn't open.)

  2. Escriba su nombre del servidor y las credenciales.Enter your server name and credentials. El nombre del servidor puede encontrarse en la hoja de la base de datos SQL y en la cadena de conexión que copió anteriormente.The server name can be found on the SQL database blade and in the connection string you copied earlier. Escriba el nombre de servidor completo, incluido database.windows.net.Type the complete server name, including database.windows.net.

    Copiar la cadena de conexión

Si se abre la ventana Nueva regla de firewall , inicie sesión en Azure y permita que SSMS cree una nueva regla de firewall.If the New Firewall Rule window opens, sign in to Azure and let SSMS create a new firewall rule for you.

Creación de una tablaCreate a table

En esta sección, creará una tabla para almacenar datos de pacientes.In this section, you will create a table to hold patient data. Inicialmente no están cifrados; configurará el cifrado en la sección siguiente.It's not initially encrypted--you will configure encryption in the next section.

  1. Expanda Bases de datos.Expand Databases.
  2. Haga clic con el botón derecho en la base de datos Clinic y haga clic en Nueva consulta.Right-click the Clinic database and click New Query.
  3. Pegue el siguiente código Transact-SQL (T-SQL) en la nueva ventana de consulta y haga clic en Ejecutar .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

Cifrado de columnas (configurar Always Encrypted)Encrypt columns (configure Always Encrypted)

SSMS proporciona un asistente para ayudar a configurar Always Encrypted fácilmente, que configura automáticamente la clave maestra de columna, la clave de cifrado de columna y las columnas cifradas.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. Expandaa Bases de datos > Clinic > Tablas.Expand Databases > Clinic > Tables.

  2. Haga clic con el botón derecho en la tabla Patients y seleccione Cifrar columnas para abrir el asistente de Always Encrypted:Right-click the Patients table and select Encrypt Columns to open the Always Encrypted wizard:

    Cifrar columnas

El Asistente para Always Encrypted incluye las siguientes secciones: Selección de columnas, Configuración de la clave maestra, Validación y Resumen.The Always Encrypted wizard includes the following sections: Column Selection, Master Key Configuration, Validation, and Summary.

Selección de columnasColumn Selection

En la página Introducción, haga clic en Siguiente para abrir la página Selección de columnas.Click Next on the Introduction page to open the Column Selection page. En esta página, seleccione las columnas que desea cifrar, el tipo de cifrado y qué clave de cifrado de columna (CEK) desea usar.On this page, you will select which columns you want to encrypt, the type of encryption, and what column encryption key (CEK) to use.

Cifre la información SSN y BirthDate de cada paciente.Encrypt SSN and BirthDate information for each patient. La columna SSN usará cifrado determinista, que admite búsquedas de igualdad, combinaciones y agrupaciones.The SSN column will use deterministic encryption, which supports equality lookups, joins, and group by. La columna BirthDate usará cifrado aleatorio, que no admite operaciones.The BirthDate column will use randomized encryption, which does not support operations.

Establezca el Tipo de cifrado de la columna SSN en Determinista y la columna BirthDate en Aleatoria.Set the Encryption Type for the SSN column to Deterministic and the BirthDate column to Randomized. Haga clic en Next.Click Next.

Cifrar columnas

Configuración de la clave maestraMaster Key Configuration

En la página Configuración de la clave maestra se configura la clave maestra de columna (CMK) y se selecciona el proveedor del almacén de claves donde se almacenará la 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. Actualmente, puede almacenar una CMK en el almacén de certificados de Windows, en Azure Key Vault o en un módulo de seguridad de hardware (HSM).Currently, you can store a CMK in the Windows certificate store, Azure Key Vault, or a hardware security module (HSM).

En este tutorial se muestra cómo almacenar las claves en Azure Key Vault.This tutorial shows how to store your keys in Azure Key Vault.

  1. Seleccione Azure Key Vault.Select Azure Key Vault.
  2. Seleccione el almacén de claves deseado en la lista desplegable.Select the desired key vault from the drop-down list.
  3. Haga clic en Next.Click Next.

Configuración de la clave maestra

ValidaciónValidation

Puede cifrar las columnas ahora o guardar un script de PowerShell para ejecutarlo más tarde.You can encrypt the columns now or save a PowerShell script to run later. Para este tutorial, seleccione Continuar para finalizar ahora y haga clic en Siguiente.For this tutorial, select Proceed to finish now and click Next.

ResumenSummary

Compruebe que la configuración sea correcta y haga clic en Finalizar para completar la configuración de Always Encrypted.Verify that the settings are all correct and click Finish to complete the setup for Always Encrypted.

Resumen

Comprobación de las acciones del asistenteVerify the wizard's actions

Una vez finalizado el asistente, la base de datos estará configurada para Always Encrypted.After the wizard is finished, your database is set up for Always Encrypted. El asistente habrá realizado las siguientes acciones:The wizard performed the following actions:

  • Creación de una clave maestra de columna (CMK) y almacenamiento en Azure Key Vault.Created a column master key and stored it in Azure Key Vault.
  • Creación de una clave de cifrado de columna (CMK) y almacenamiento en Azure Key Vault.Created a column encryption key and stored it in Azure Key Vault.
  • Configuración de las columnas seleccionadas para el cifrado.Configured the selected columns for encryption. La tabla Patients aún no tiene datos, pero los datos existentes en las columnas seleccionadas ahora están cifrados.The Patients table currently has no data, but any existing data in the selected columns is now encrypted.

Para comprobar la creación de las claves en SSMS, expanda Clinic > Seguridad > Claves de Always Encrypted.You can verify the creation of the keys in SSMS by expanding Clinic > Security > Always Encrypted Keys.

Crear una aplicación cliente que funcione con los datos cifradosCreate a client application that works with the encrypted data

Ahora que Always Encrypted está configurado, vamos a crear una aplicación que realice operaciones de inserción y selección en las columnas cifradas.Now that Always Encrypted is set up, you can build an application that performs inserts and selects on the encrypted columns.

Importante

La aplicación debe usar objetos SqlParameter al pasar datos de texto sin cifrar al servidor con columnas de Always Encrypted.Your application must use SqlParameter objects when passing plaintext data to the server with Always Encrypted columns. Se generará una excepción al pasar valores literales sin usar objetos SqlParameter.Passing literal values without using SqlParameter objects will result in an exception.

  1. Abra Visual Studio y cree una nueva Aplicación de consola de C# (Visual Studio 2015 y versiones anteriores) o una Aplicación de consola (.NET Framework) (Visual Studio 2017 y versiones posteriores).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). Asegúrese de que el proyecto esté establecido en .NET Framework 4.6 o versiones posteriores.Make sure your project is set to .NET Framework 4.6 or later.
  2. Use el nombre AlwaysEncryptedConsoleAKVApp para el proyecto y haga clic en Aceptar.Name the project AlwaysEncryptedConsoleAKVApp and click OK.
  3. Instale los siguientes paquetes NuGet; para ello, vaya aHerramientas > Administrador de paquetes NuGet > Consola del Administrador de paquetes.Install the following NuGet packages by going to Tools > NuGet Package Manager > Package Manager Console.

Ejecute estas dos líneas de código en la Consola del Administrador de paquetes:Run these two lines of code in the Package Manager Console:

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

Modificar la cadena de conexión para habilitar Always EncryptedModify your connection string to enable Always Encrypted

En esta sección se explica cómo habilitar Always Encrypted en la cadena de conexión de su base de datos.This section explains how to enable Always Encrypted in your database connection string.

Para habilitar Always Encrypted, debe agregar la palabra clave Column Encryption Setting a la cadena de conexión y establecerla en Enabled.To enable Always Encrypted, you need to add the Column Encryption Setting keyword to your connection string and set it to Enabled.

Puede establecerla directamente en la cadena de conexión o mediante SqlConnectionStringBuilder.You can set this directly in the connection string, or you can set it by using SqlConnectionStringBuilder. La aplicación de ejemplo de la siguiente sección muestra cómo usar SqlConnectionStringBuilder.The sample application in the next section shows how to use SqlConnectionStringBuilder.

Modificar Always Encrypted en la cadena de conexiónEnable Always Encrypted in the connection string

Agregue la siguiente palabra clave a la cadena de conexión.Add the following keyword to your connection string.

Column Encryption Setting=Enabled

Habilitar Always Encrypted con SqlConnectionStringBuilderEnable Always Encrypted with SqlConnectionStringBuilder

El siguiente código muestra cómo habilitar Always Encrypted estableciendo SqlConnectionStringBuilder.ColumnEncryptionSetting en Enabled.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;

Registro del proveedor de Azure Key VaultRegister the Azure Key Vault provider

El código siguiente muestra cómo registrar el proveedor de Azure Key Vault con el controlador de 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);
}

Aplicación de consola de ejemplo de Always EncryptedAlways Encrypted sample console application

En este ejemplo se muestra cómo:This sample demonstrates how to:

  • Modificar la cadena de conexión para habilitar Always Encrypted.Modify your connection string to enable Always Encrypted.
  • Registrar Azure Key Vault como proveedor de almacén de claves de la aplicación.Register Azure Key Vault as the application's key store provider.
  • Insertar datos en las columnas cifradas.Insert data into the encrypted columns.
  • Seleccionar un registro mediante el filtrado de un valor específico de una columna cifrada.Select a record by filtering for a specific value in an encrypted column.

Reemplace el contenido de Program.cs por el código siguiente.Replace the contents of Program.cs with the following code. Reemplace la cadena de conexión para la variable global connectionString en la línea directamente anterior al método Main por una cadena de conexión válida desde el Portal de 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. Este es el único cambio que necesita realizar en este código.This is the only change you need to make to this code.

Ejecute la aplicación para ver Always Encrypted en acción.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; }
    }
}

Comprobación del cifrado de los datosVerify that the data is encrypted

Para comprobar rápidamente que los datos reales del servidor están cifrados, podemos consultar los datos de los pacientes con SSMS (mediante la conexión actual en la que el parámetro Column Encryption Setting aún no está habilitado).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).

Ejecute la siguiente consulta en la base de datos Clinic.Run the following query on the Clinic database.

SELECT FirstName, LastName, SSN, BirthDate FROM Patients;

Puede ver que las columnas cifradas no contienen datos de texto no cifrado.You can see that the encrypted columns do not contain any plaintext data.

Nueva aplicación de consola

Para usar SSMS para acceder a los datos de texto simple, primero deberá asegurarse de que el usuario tiene los permisos adecuados para Azure Key Vault: get, unwrapKey y 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. Para obtener información detallada, consulte Creación y almacenamiento de claves maestras de columna (Always Encrypted).For detailed information, see Create and Store Column Master Keys (Always Encrypted).

A continuación, agregue el parámetro Column Encryption Setting=enabled durante la conexión.Then add the Column Encryption Setting=enabled parameter during your connection.

  1. En SSMS, haga clic con el botón derecho en el servidor en el Explorador de objetos y elija Desconectar.In SSMS, right-click your server in Object Explorer and choose Disconnect.

  2. Haga clic en Conectar > Motor de base de datos para abrir la ventana Conectar con el servidor y haga clic en Opciones.Click Connect > Database Engine to open the Connect to Server window and click Options.

  3. Haga clic en Parámetros de conexión adicionales y escriba Column Encryption Setting=enabled.Click Additional Connection Parameters and type Column Encryption Setting=enabled.

    Nueva aplicación de consola

  4. Ejecute la siguiente consulta en la base de datos Clinic.Run the following query on the Clinic database.

    SELECT FirstName, LastName, SSN, BirthDate FROM Patients;
    

    Ahora puede ver los datos de texto no cifrado en las columnas cifradas.You can now see the plaintext data in the encrypted columns. Nueva aplicación de consolaNew console application

Pasos siguientesNext steps

Después de crear una base de datos que usa Always Encrypted, es posible que quiera hacer lo siguiente:After you create a database that uses Always Encrypted, you may want to do the following: