Using Always Encrypted with the .NET Framework Data Provider for SQL Server (Использование Always Encrypted с поставщиком данных .NET Framework для SQL Server)

Область применения: SQL Server База данных SQL Azure Управляемый экземпляр SQL Azure

В этой статье содержится информация о том, как разрабатывать приложения .NET Framework с помощью Always Encrypted или Always Encrypted with secure enclaves и поставщика данных .NET Framework для SQL Server (System.Data.SqlClient).

Примечание.

Использование поставщика данных .NET Framework для SQL Server (System.Data.SqlClient) не рекомендуется для новых разработок. Дополнительные сведения см. в разделе System.Data.SqlClient.

Функция Always Encrypted позволяет шифровать конфиденциальные данные в клиентских приложениях, не раскрывая данные или ключи шифрования для SQL Server или Базы данных SQL Azure. Драйвер с поддержкой постоянного шифрования, такой как поставщик данных .NET Framework для SQL Server, реализует это за счет прозрачного шифрования и расшифровки конфиденциальных данных в клиентском приложении SQL Server. Драйвер автоматически определяет, какие параметры запроса соответствуют важным столбцам базы данных (защищенным с помощью Always Encrypted), и шифрует значения этих параметров перед передачей данных в SQL Server или Базу данных SQL Azure. Аналогичным образом драйвер прозрачно расшифровывает данные, полученные из зашифрованных столбцов базы в результатах запроса. Дополнительные сведения см. в разделе Разработка приложений с помощью Always Encrypted и Разработка приложений с помощью Always Encrypted с безопасными анклавами.

Примечание.

Поставщик данных .NET Framework для SQL Server (System.Data.SqlClient) не поддерживает работу с анклавами VBS без аттестации.

Предварительные требования

  • Настройте функцию постоянного шифрования в базе данных. В процесс настройки входят действия по подготовке ключей постоянного шифрования и настройке шифрования для выбранных столбцов базы данных. Если у вас еще нет базы данных с настроенным Always Encrypted, следуйте инструкциям в руководстве по началу работы с Always Encrypted.
  • Если вы используете Always Encrypted с безопасными анклавами, см. статью Разработка приложений с помощью Always Encrypted с безопасными анклавами со сведениями о дополнительных предварительных требованиях.
  • Убедитесь, что на компьютере, предназначенном для разработки, установлена платформа .NET Framework 4.6.1 или более поздней версии. Дополнительные сведения см. в разделе .NET Framework 4.6. Также необходимо убедиться, что в среде разработки в качестве целевой версии платформы установлена платформа .NET Framework 4.6 или более поздней версии. Если вы используете Visual Studio, обратитесь к разделу Практическое руководство. Выбор целевой версии платформы .NET Framework.

Примечание.

Уровень поддержки постоянного шифрования зависит от конкретной версии платформы .NET Framework. Ссылки на API Always Encrypted перечислены в следующих разделах.

Включение постоянного шифрования для запросов приложений

Самым простым способом включения шифрования параметров и расшифровки результатов запросов к зашифрованным столбцам является установка для ключевого слова строки подключения "Параметр шифрования столбца" значения Включено.

Ниже приведен пример строки подключения, включающий постоянное шифрование.

string connectionString = "Data Source=server63; Initial Catalog=Clinic; Integrated Security=true; Column Encryption Setting=enabled";
SqlConnection connection = new SqlConnection(connectionString);

Далее приведен эквивалент примера с использованием свойства SqlConnectionStringBuilder.ColumnEncryptionSetting.

SqlConnectionStringBuilder strbldr = new SqlConnectionStringBuilder();
strbldr.DataSource = "server63";
strbldr.InitialCatalog = "Clinic";
strbldr.IntegratedSecurity = true;
strbldr.ColumnEncryptionSetting = SqlConnectionColumnEncryptionSetting.Enabled;
SqlConnection connection = new SqlConnection(strbldr.ConnectionString);

Постоянное шифрование также можно включить для отдельных запросов. См. раздел Управление влиянием постоянного шифрования на производительность ниже. Включения функции Always Encrypted недостаточно для успешного шифрования или расшифровки. Необходимо также проверить выполнение следующих условий:

  • У приложения есть разрешения базы данных VIEW ANY COLUMN MASTER KEY DEFINITION и VIEW ANY COLUMN ENCRYPTION KEY DEFINITION, которые необходимы для доступа к метаданным о ключах Always Encrypted в базе данных. Для дополнительных сведений см. страницу о разрешениях в статье "Always Encrypted (ядро СУБД)".
  • Приложение может получить доступ к главному ключу столбца, который защищает ключи шифрования столбцов, шифрующие запрашиваемые столбцы базы данных.

Включение Always Encrypted с защищёнными анклавами

Начиная с версии .NET Framework 4.7.2, драйвер поддерживает Always Encrypted with secure enclaves.

Общие сведения о роли клиентского драйвера в вычислениях анклава и аттестации анклава см. в статье Разработка приложений с помощью Always Encrypted с безопасными анклавами.

Настройка приложения:

  1. Включите Always Encrypted для запросов приложения, как описано в предыдущем разделе.

  2. Интегрируйте пакет NuGet Microsoft.SqlServer.Management.AlwaysEncrypted.EnclaveProviders в приложение. NuGet — это библиотека поставщиков анклавов, которая реализует логику на стороне клиента для протокола аттестации, а также для установки безопасного канала с безопасным анклавом.

  3. Измените конфигурацию приложения (например, в файле web.config или app.config), чтобы определить сопоставление типа анклава, настроенного для базы данных, и поставщика анклава.

    1. Если вы используете SQL Server и Host Guardian Service (HGS), необходимо сопоставить тип анклава VBS с классом Microsoft.SqlServer.Management.AlwaysEncrypted.EnclaveProviders.HostGuardianServiceEnclaveProvider из пакета NuGet.
    2. Если вы используете Базы данных SQL Azure и Microsoft Аттестация Azure, необходимо сопоставить тип анклава SGX с классом Microsoft.SqlServer.Management.AlwaysEncrypted.EnclaveProviders.AzureAttestationEnclaveProvider, поставляемым в пакете NuGet.

    Подробные инструкции о том, как изменить конфигурацию приложения, см. в руководстве Руководство: разработка приложения на платформе .NET Framework с использованием Always Encrypted и безопасных анклавов.

  4. В строке подключения к базе данных задайте для параметра Enclave Attestation URL URL-адрес аттестации (конечную точку службы аттестации). Необходимо получить URL-адрес аттестации для вашей среды у администратора службы аттестации.

    1. Если вы используете SQL Server и Host Guardian Service (HGS), см. Определение URL-адреса аттестации HGS и предоставление общего доступа к нему.
    2. Если вы используете База данных SQL Azure и Microsoft Аттестация Azure, см. Определение URL-адреса аттестации для политики аттестации.

Пошаговое руководство см. в разделе Руководство: разработка приложения .NET Framework с использованием Always Encrypted с безопасными анклавами

Получение и изменение данных в зашифрованных столбцах

После включения постоянного шифрования для запросов приложений можно использовать стандартные API-интерфейсы для ADO.NET (см. раздел Получение и изменение данных в ADO.NET) или API-интерфейсы поставщика данных .NET Framework для SQL Server , определенные в пространстве имен System.Data.SqlClient, чтобы получать или изменять данные в зашифрованных столбцах базы данных. Если приложение имеет необходимые разрешения для базы данных и может обращаться к главному ключу столбца, поставщик данных .NET Framework для SQL Server будет шифровать все параметры запроса, предназначенные для зашифрованных столбцов, и расшифровывать данные, извлекаемые из зашифрованных столбцов с возвращаемыми значениями типов .NET в виде открытого текста, которые соответствуют типам данным SQL Server, заданным для столбцов в схеме базы данных. Если функция Always Encrypted не включена, выполнение запросов с параметрами, предназначенными для зашифрованных столбцов, завершится ошибкой. Запросы по-прежнему могут получать данные из зашифрованных столбцов, пока для них не будут указаны параметры, предназначенные для зашифрованных столбцов. Однако поставщик данных .NET Framework для SQL Server не будет пытаться расшифровать все значения, полученные из зашифрованных столбцов, и приложение будет получать двоичные зашифрованные данные (в виде массивов байтов).

В приведенной ниже таблице описывается поведение запросов в зависимости от того, включено постоянное шифрование или нет.

Характеристика запроса Постоянное шифрование включено, и приложение может получать доступ к ключам и метаданным ключей Функция Always Encrypted включена, и приложение не может получать доступ к ключам и метаданным ключей Постоянное шифрование отключено
Запросы с параметрами, предназначенными для зашифрованных столбцов. Значения параметров прозрачно шифруются. Ошибка Ошибка
Запросы, получающие данные из зашифрованных столбцов, без параметров, предназначенных для зашифрованных столбцов. Результаты из зашифрованных столбцов прозрачно расшифровываются. Приложение получает значения типов данных .NET в виде открытого текста, которые соответствуют типам SQL Server, настроенным для зашифрованных столбцов. Ошибка Результаты из зашифрованных столбцов не расшифровываются. Приложение получает зашифрованные значения в виде массивов байтов (byte[]).

В следующих примерах показано получение и изменение данных в зашифрованных столбцах. В примерах предполагается использование целевой таблицы с приведенной ниже схемой. Столбцы SSN и BirthDate зашифрованы.

CREATE TABLE [dbo].[Patients]([PatientId] [int] IDENTITY(1,1), 
 [SSN] [char](11) COLLATE Latin1_General_BIN2 
 ENCRYPTED WITH (ENCRYPTION_TYPE = DETERMINISTIC, 
 ALGORITHM = 'AEAD_AES_256_CBC_HMAC_SHA_256', 
 COLUMN_ENCRYPTION_KEY = CEK1) NOT NULL,
 [FirstName] [nvarchar](50) NULL,
 [LastName] [nvarchar](50) NULL, 
 [BirthDate] [date] 
 ENCRYPTED WITH (ENCRYPTION_TYPE = RANDOMIZED, 
 ALGORITHM = 'AEAD_AES_256_CBC_HMAC_SHA_256', 
 COLUMN_ENCRYPTION_KEY = CEK1) NOT NULL
 PRIMARY KEY CLUSTERED ([PatientId] ASC) ON [PRIMARY])
 GO

Пример вставки данных

В этом примере в таблицу Patients вставляется строка. Обратите внимание на следующее:

  • В примере кода нет ничего, связанного с шифрованием. Поставщик данных .NET Framework для SQL Server автоматически обнаруживает и шифрует параметры paramSSN и paramBirthdate , предназначенные для зашифрованных столбцов. В этом случае шифрование является прозрачным для приложения.
  • Значения, вставляемые в столбцы базы данных, включая зашифрованные столбцы, передаются как объекты SqlParameter . Несмотря на то, что при отправке значений в незашифрованные столбцы использовать параметр SqlParameter необязательно (но настоятельно рекомендуется, так как он помогает предотвратить внедрение кода SQL), он требуется для значений, предназначенных для зашифрованных столбцов. Если значения, вставляемые в столбцы SSN или BirthDate, были переданы в виде литералов, внедренных в инструкцию запроса, запрос завершится ошибкой, так как поставщик данных платформа .NET Framework для SQL Server не сможет определить значения в целевых зашифрованных столбцах, поэтому он не зашифрует значения. В результате сервер отклонит их как несовместимые с зашифрованными столбцами.
  • Для типа данных параметра, предназначенного для столбца SSN, задана строка ANSI (отличная от Юникода), которая сопоставляется с типом данных char и varchar SQL Server. Если для параметра был задан тип Unicode-строки (String), который сопоставляется с nchar/nvarchar, запрос завершился бы ошибкой, так как Always Encrypted не поддерживает преобразования из зашифрованных значений nchar/nvarchar в зашифрованные значения char/varchar. Сведения о сопоставлении типов данных см. в разделе Сопоставления типов данных SQL Server .
  • В качестве типа данных параметра, вставляемого в столбец BirthDate, явным образом задан целевой тип данных SQL Server. Для этого использовалось свойство SqlParameter.SqlDbType Property, а не неявное сопоставление типов .NET с типами данных SQL Server, применяемыми при работе со свойством SqlParameter.DbType Property. По умолчанию структура DateTime сопоставляется с типом данных datetime SQL Server. Так как тип данных столбца BirthDate имеет дату и Always Encrypted не поддерживает преобразование зашифрованных значений даты и времени в зашифрованные значения даты, используя сопоставление по умолчанию, приведет к ошибке.
string connectionString = "Data Source=server63; Initial Catalog=Clinic; Integrated Security=true; Column Encryption Setting=enabled";
using (SqlConnection connection = new SqlConnection(strbldr.ConnectionString))
{
   using (SqlCommand cmd = connection.CreateCommand())
   {
      cmd.CommandText = @"INSERT INTO [dbo].[Patients] ([SSN], [FirstName], [LastName], [BirthDate]) VALUES (@SSN, @FirstName, @LastName, @BirthDate);";

      SqlParameter paramSSN = cmd.CreateParameter();
      paramSSN.ParameterName = @"@SSN";
      paramSSN.DbType = DbType.AnsiStringFixedLength;
      paramSSN.Direction = ParameterDirection.Input;
      paramSSN.Value = "795-73-9838";
      paramSSN.Size = 11;
      cmd.Parameters.Add(paramSSN);

      SqlParameter paramFirstName = cmd.CreateParameter();
      paramFirstName.ParameterName = @"@FirstName";
      paramFirstName.DbType = DbType.String;
      paramFirstName.Direction = ParameterDirection.Input;
      paramFirstName.Value = "Catherine";
      paramFirstName.Size = 50;
      cmd.Parameters.Add(paramFirstName);

      SqlParameter paramLastName = cmd.CreateParameter();
      paramLastName.ParameterName = @"@LastName";
      paramLastName.DbType = DbType.String;
      paramLastName.Direction = ParameterDirection.Input;
      paramLastName.Value = "Abel";
      paramLastName.Size = 50;
      cmd.Parameters.Add(paramLastName);

      SqlParameter paramBirthdate = cmd.CreateParameter();
      paramBirthdate.ParameterName = @"@BirthDate";
      paramBirthdate.SqlDbType = SqlDbType.Date;
      paramBirthdate.Direction = ParameterDirection.Input;
      paramBirthdate.Value = new DateTime(1996, 09, 10);
      cmd.Parameters.Add(paramBirthdate);

      cmd.ExecuteNonQuery();
   } 
}

Пример получения данных в открытом виде

В следующем примере показана фильтрация данных на основе зашифрованных значений и получение данных в виде открытого текста из зашифрованных столбцов. Обратите внимание на следующее:

  • Значение, используемое в предложении WHERE для фильтрации по столбцу SSN, необходимо передать с помощью SqlParameter, чтобы поставщик данных .NET Framework для SQL Server мог его прозрачно зашифровать перед отправкой в базу данных.
  • Все значения, выводимые программой, будут представлены в виде обычного текста, так как поставщик данных .NET Framework для SQL Server прозрачно расшифровывает данные, полученные из столбцов SSN и BirthDate.

Примечание.

Запросы могут выполнять сравнение на равенство для столбцов, если они шифруются с помощью детерминированного шифрования. Дополнительные сведения см. в разделе Выбор детерминированного или случайного шифрования.

string connectionString = "Data Source=server63; Initial Catalog=Clinic; Integrated Security=true; Column Encryption Setting=enabled";
    
using (SqlConnection connection = new SqlConnection(strbldr.ConnectionString))
 {
    using (SqlCommand cmd = connection.CreateCommand())
 {

 cmd.CommandText = @"SELECT [SSN], [FirstName], [LastName], [BirthDate] FROM [dbo].[Patients] WHERE SSN=@SSN";
 SqlParameter paramSSN = cmd.CreateParameter();
 paramSSN.ParameterName = @"@SSN";
 paramSSN.DbType = DbType.AnsiStringFixedLength;
 paramSSN.Direction = ParameterDirection.Input;
 paramSSN.Value = "795-73-9838";
 paramSSN.Size = 11;
 cmd.Parameters.Add(paramSSN);
 using (SqlDataReader reader = cmd.ExecuteReader())
 {
   if (reader.HasRows)
 {
 while (reader.Read())
 {
    Console.WriteLine(@"{0}, {1}, {2}, {3}", reader[0], reader[1], reader[2], ((DateTime)reader[3]).ToShortDateString());
 }

Пример получения зашифрованных данных

Если функция Always Encrypted не включена, запрос может получать данные из зашифрованных столбцов, пока для него не будут указаны параметры, предназначенные для зашифрованных столбцов.

В следующем примере показано извлечение двоичных зашифрованных данных из зашифрованных столбцов. Обратите внимание на следующее:

  • Так как Always Encrypted не включается в строке подключения, запрос вернет зашифрованные значения SSN и BirthDate в виде байтовых массивов (программа преобразует эти значения в строки).
  • Запрос, получающий данные из зашифрованных столбцов с отключенным постоянным шифрованием, может иметь параметры при условии, что ни один из параметров не предназначен для зашифрованного столбца. Приведенный выше запрос выполняет фильтрацию по LastName, который не зашифрован в базе данных. Запрос, отфильтрованный по SSN или BirthDate, завершится ошибкой.
string connectionString = "Data Source=server63; Initial Catalog=Clinic; Integrated Security=true";
                
using (SqlConnection connection = new SqlConnection(connectionString))
{
   connection.Open();
   using (SqlCommand cmd = connection.CreateCommand())
   {
      cmd.CommandText = @"SELECT [SSN], [FirstName], [LastName], [BirthDate] FROM [dbo].[Patients] WHERE [LastName]=@LastName";
      SqlParameter paramLastName = cmd.CreateParameter();
      paramLastName.ParameterName = @"@LastName";
      paramLastName.DbType = DbType.String;
      paramLastName.Direction = ParameterDirection.Input;
      paramLastName.Value = "Abel";
      paramLastName.Size = 50;
      cmd.Parameters.Add(paramLastName);
      using (SqlDataReader reader = cmd.ExecuteReader())
      {
         if (reader.HasRows)
         {
            while (reader.Read())
         {
         Console.WriteLine(@"{0}, {1}, {2}, {3}", BitConverter.ToString((byte[])reader[0]), reader[1], reader[2], BitConverter.ToString((byte[])reader[3]));
      }
   }
}

Как избежать распространенных проблем при запросе зашифрованных столбцов

В этом разделе описываются общие категории ошибок, возникающих при выполнении запросов к зашифрованным столбцам из приложений .NET, и приводятся рекомендации о том, как их избежать.

Ошибки преобразования неподдерживаемых типов данных

Постоянное шифрование поддерживает несколько преобразований для зашифрованных типов данных. Подробный список поддерживаемых преобразований типов см. в статье Always Encrypted. Чтобы избежать ошибок при преобразовании типов данных, сделайте следующее:

  • Задайте типы параметров, предназначенных для зашифрованных столбцов, так, чтобы тип данных SQL Server параметра точно совпадал с типом целевого столбца или чтобы поддерживалось преобразование типа данных SQL Server параметра в целевой тип столбца. С помощью свойства SqlParameter.SqlDbType можно принудительно задать нужное сопоставление типов данных .NET с конкретными типами данных SQL Server.
  • Убедитесь, что точность и масштаб параметров, предназначенных для столбцов типов данных SQL Server decimal и numeric, соответствуют точности и масштабу, настроенным для целевого столбца.
  • Убедитесь, что точность параметров, предназначенных для столбцов типов данных SQL Server datetime2, datetimeoffset или time, не превышает точность для целевого столбца (в запросах, которые изменяют значения целевого столбца).

Ошибки, возникающие из-за передачи значений в виде открытого текста, а не в зашифрованном виде

Любое значение, предназначенное для зашифрованного столбца, должно быть зашифровано внутри приложения. Попытка вставки, изменения или фильтрации по значению в виде открытого текста в зашифрованном столбце приведет к возникновению ошибки, подобной следующей:

System.Data.SqlClient.SqlException (0x80131904): Operand type clash: varchar is incompatible with varchar(8000) encrypted with (encryption_type = 'DETERMINISTIC', encryption_algorithm_name = 'AEAD_AES_256_CBC_HMAC_SHA_256', column_encryption_key_name = 'CEK_Auto1', column_encryption_key_database_name = 'Clinic') collation_name = 'SQL_Latin1_General_CP1_CI_AS'

Чтобы избежать таких ошибок, убедитесь, что:

  • функция Always Encrypted включена для запросов приложений, предназначенных для зашифрованных столбцов (для строки подключения или в отдельном объекте SqlCommand для конкретного запроса);
  • для отправки данных, предназначенных для зашифрованных столбцов, используется параметр SqlParameter. В следующем примере показан запрос, который неправильно выполняет фильтрацию по литералу/константе в зашифрованном столбце (SSN) вместо передачи литерала в объекте SqlParameter.
using (SqlCommand cmd = connection.CreateCommand())
{
   cmd.CommandText = @"SELECT [SSN], [FirstName], [LastName], [BirthDate] FROM [dbo].[Patients] WHERE SSN='795-73-9838'";
cmd.ExecuteNonQuery();
}

Работа с хранилищами главных ключей столбцов

Чтобы зашифровать значение параметра или расшифровать данные в результатах запроса, поставщику данных .NET Framework для SQL Server необходимо получить ключ шифрования столбца, настроенный для целевого столбца. Ключи шифрования столбцов хранятся в зашифрованном виде в метаданных базы данных. Каждому ключу шифрования столбца соответствует главный ключ столбца, который использовался для его шифрования. Метаданные базы данных не хранят главные ключи столбцов, а содержат только сведения о хранилище ключей, содержащего главный ключ столбца и расположение ключа в хранилище ключей.

Чтобы получить значение в виде открытого текста для ключа шифрования столбца, поставщик данных .NET Framework для SQL Server сначала получает метаданные о ключе шифрования столбца и соответствующем ему главном ключе столбца, а затем использует сведения в метаданных для доступа в хранилище ключей, содержащее главный ключ столбца, и для расшифровки ключа шифрования зашифрованных столбцов. Поставщик данных .NET Framework для SQL Server взаимодействует с хранилищем ключей с помощью поставщика хранилища главных ключей столбцов, который является экземпляром класса, производным от класса SqlColumnEncryptionKeyStoreProvider.

Процедура получения ключа шифрования столбца:

  1. Если Always Encrypted включено для запроса, поставщик данных .NET Framework для SQL Server прозрачно вызывает sys.sp_describe_parameter_encryption , чтобы получить метаданные шифрования для параметров, предназначенных для зашифрованных столбцов, если запрос содержит параметры. Для зашифрованных данных, содержащихся в результатах запроса, SQL Server автоматически присоединяет метаданные шифрования. Сведения о главном ключе столбца включают в себя следующее:

    • Имя поставщика хранилища ключей, который инкапсулирует хранилище ключей, содержащее главный ключ столбца.
    • Путь к ключу, указывающий расположение главного ключа столбца в хранилище ключей.

    Сведения о ключе шифрования столбца включают в себя следующее:

    • Зашифрованное значение ключа шифрования столбца.
    • Имя алгоритма, который использовался для шифрования ключа шифрования столбца.
  2. Поставщик данных .NET Framework для SQL Server использует имя поставщика хранилища главных ключей столбцов для поиска объекта поставщика (экземпляр класса, производного от класса SqlColumnEncryptionKeyStoreProvider) во внутренней структуре данных.

  3. Чтобы расшифровать ключ шифрования столбца, поставщик данных .NET Framework для SQL Server вызывает метод SqlColumnEncryptionKeyStoreProvider.DecryptColumnEncryptionKey, передавая путь к главному ключу столбца, зашифрованное значение ключа шифрования столбца и имя алгоритма шифрования, используемого для создания ключа шифрования зашифрованных столбцов.

Использование встроенных поставщиков хранилища главных ключей столбцов

В состав поставщика данных .NET Framework для SQL Server входят следующие встроенные поставщики хранилища главных ключей столбцов, которые предварительно зарегистрированы с конкретными именами поставщиков (используемыми для поиска поставщика).

Класс Описание Имя поставщика для поиска
Класс SqlColumnEncryptionCertificateStoreProvider Поставщик для хранилища сертификатов Windows. MSSQL_CERTIFICATE_STORE
Класс SqlColumnEncryptionCngProvider

Примечание. Этот поставщик доступен в .NET Framework 4.6.1 или более поздней версии.
Поставщик хранилища ключей, поддерживающий Microsoft Cryptography API: Next Generation (CNG) API. Как правило, такое хранилище представляет собой аппаратный модуль безопасности — физическое устройство, которое защищает цифровые ключи и управляет ими, а также обеспечивает обработку шифрования. MSSQL_CNG_STORE
Класс SqlColumnEncryptionCspProvider

Примечание. Этот поставщик доступен в .NET Framework 4.6.1 или более поздней версии.
Поставщик хранилища ключей, поддерживающий Microsoft Cryptography API (CAPI). Как правило, такое хранилище представляет собой аппаратный модуль безопасности — физическое устройство, которое защищает цифровые ключи и управляет ими, а также обеспечивает обработку шифрования. MSSQL_CSP_PROVIDER

Вам не нужно вносить изменения в код приложения для использования этих поставщиков, но обратите внимание на следующее:

  • Вы (или ваш администратор баз данных) должны убедиться, что имя поставщика, указанное в метаданных главного ключа столбца, задано правильно, а путь к главному ключу столбца соответствует формату пути к ключу, допустимому для данного поставщика. Рекомендуется настроить ключи с помощью таких средств, как SQL Server Management Studio, которые автоматически создают допустимые имена поставщиков и пути ключей при выдаче CREATE COLUMN MASTER KEY инструкции (Transact-SQL) . Дополнительные сведения см. в разделах Configuring Always Encrypted using SQL Server Management Studio (Настройка Always Encrypted с помощью среды SQL Server Management Studio ) и Настройка постоянного шифрования с помощью PowerShell.
  • Убедитесь, что приложение может получить доступ к ключу в хранилище ключей. Для этого может потребоваться предоставить приложению доступ к ключу или хранилищу ключей (в зависимости от хранилища ключей) или выполнить другие действия по настройке конкретного хранилища ключей. Например, чтобы получить доступ к хранилищу ключей, реализующим CNG или CAPI (например, аппаратный модуль безопасности), необходимо убедиться, что на компьютере приложения установлена библиотека, реализуемая CNG или CAPI для вашего хранилища. Дополнительные сведения см. в разделе Создание и хранение главных ключей столбцов для Always Encrypted.

Использование поставщика хранилища ключей Azure

Azure Key Vault — удобное решение для хранения главных ключей столбцов и управления ими в Always Encrypted, особенно если ваши приложения размещены в Azure. Поставщик данных .NET Framework для SQL Server не включает встроенный поставщик хранилища главных ключей столбцов для Azure Key Vault, но он доступен в виде пакета NuGet, который можно легко интегрировать в приложение. Подробная информация доступна в следующих статьях:

Реализация настраиваемого поставщика хранилища главных ключей столбцов

Если вы хотите сохранить главные ключи столбцов в хранилище ключей, которое не поддерживается существующим поставщиком, можно реализовать настраиваемый поставщик, расширив класс SqlColumnEncryptionCngProvider и зарегистрировав поставщика с помощью метода SqlConnection.RegisterColumnEncryptionKeyStoreProviders.

public class MyCustomKeyStoreProvider : SqlColumnEncryptionKeyStoreProvider
    {
        public override byte[] EncryptColumnEncryptionKey(string masterKeyPath, string encryptionAlgorithm, byte[] columnEncryptionKey)
        {
            // Logic for encrypting a column encrypted key.
        }
        public override byte[] DecryptColumnEncryptionKey(string masterKeyPath, string encryptionAlgorithm, byte[] EncryptedColumnEncryptionKey)
        {
            // Logic for decrypting a column encrypted key.
        }
    }  
    class Program
    {
        static void Main(string[] args)
        {
            Dictionary\<string, SqlColumnEncryptionKeyStoreProvider> providers =
               new Dictionary\<string, SqlColumnEncryptionKeyStoreProvider>();
            providers.Add("MY_CUSTOM_STORE", customProvider);
            SqlConnection.RegisterColumnEncryptionKeyStoreProviders(providers);
            providers.Add(SqlColumnEncryptionCertificateStoreProvider.ProviderName, customProvider);
            SqlConnection.RegisterColumnEncryptionKeyStoreProviders(providers); 
       // ...
        }

    }

Использование поставщиков хранилищ главных ключей столбцов для программной подготовки ключей

При доступе к зашифрованным столбцам поставщик данных .NET Framework для SQL Server прозрачно находит и вызывает нужный поставщик хранилища главных ключей столбцов, чтобы расшифровать ключи шифрования столбцов. Как правило, обычный код приложения не вызывает поставщики хранилища главных ключей напрямую. Однако вы можете явным образом создать экземпляр поставщика и вызвать его, чтобы программно подготавливать ключи Always Encrypted и управлять ими: например, чтобы создать зашифрованный ключ шифрования столбца и расшифровать ключ шифрования столбца (например, при ротации главного ключа столбца). Дополнительные сведения см. в разделе Общие сведения об управлении ключами для Always Encrypted. Реализация собственных средств управления ключами может потребоваться только в том случае, если используется настраиваемый поставщик хранилища ключей. При использовании ключей, хранящихся в хранилище ключей Azure или в другом хранилище ключей, для которого существует встроенный поставщик, вы можете применять для управления ключами и подготовки ключей любые существующие средства, в том числе SQL Server Management Studio или PowerShell. В примере ниже показано создание ключа шифрования столбца и использование класса SqlColumnEncryptionCertificateStoreProvider для шифрования ключа с помощью сертификата.

using System.Security.Cryptography;
static void Main(string[] args)
{
    byte[] EncryptedColumnEncryptionKey = GetEncryptedColumnEncryptionKey(); 
    Console.WriteLine("0x" + BitConverter.ToString(EncryptedColumnEncryptionKey).Replace("-", "")); 
    Console.ReadKey();
}

static byte[]  GetEncryptedColumnEncryptionKey()
{
    int cekLength = 32;
    String certificateStoreLocation = "CurrentUser";
    String certificateThumbprint = "AA11BB22CC33DD44EE55FF66AA77BB88CC99DD00";
    // Generate the plaintext column encryption key.
    byte[] columnEncryptionKey = new byte[cekLength];
    RNGCryptoServiceProvider rngCsp = new RNGCryptoServiceProvider();
    rngCsp.GetBytes(columnEncryptionKey);

    // Encrypt the column encryption key with a certificate.
    string keyPath = String.Format(@"{0}/My/{1}", certificateStoreLocation, certificateThumbprint);
    SqlColumnEncryptionCertificateStoreProvider provider = new SqlColumnEncryptionCertificateStoreProvider();
    return provider.EncryptColumnEncryptionKey(keyPath, @"RSA_OAEP", columnEncryptionKey); 
}

Управление влиянием постоянного шифрования на производительность

Поскольку постоянное шифрование является технологией шифрования на стороне клиента, значительное влияние на производительность происходит на стороне клиента, а не в базе данных. Помимо затрат на операции шифрования и расшифровки существуют и другие источники снижения производительности на стороне клиента:

  • Дополнительные обращения к базе данных для получения метаданных для параметров запроса.
  • Вызовы хранилища главных ключей столбцов для доступа к главному ключу столбца.

В этом разделе описываются процессы оптимизации производительности, встроенные в поставщик .NET Framework для SQL Server, и способы управления влиянием двух указанных выше факторов на производительность.

Управление количеством циклов обмена при получении метаданных для параметров запроса

Если для соединения включена функция Always Encrypted, по умолчанию поставщик данных .NET Framework для SQL Server будет вызывать sys.sp_describe_parameter_encryption для каждого параметризованного запроса, передавая инструкцию запроса (без значений параметров) в SQL Server. sys.sp_describe_parameter_encryption анализирует инструкцию запроса и для каждого параметра, который должен быть зашифрован, возвращает связанные с шифрованием сведения, позволяющие поставщику данных .NET Framework для SQL Server шифровать значения параметров. Описанное выше поведение обеспечивает высокий уровень прозрачности для клиентского приложения. Пока значения, предназначенные для зашифрованных столбцов, передаются поставщику данных .NET Framework для SQL Server в объектах SqlParameter, приложению (и разработчику приложений) не требуется знать, какие запросы получают доступ к зашифрованным столбцам.

Кэширование метаданных запроса

В платформе .NET Framework 4.6.2 и более поздней версии поставщик данных .NET Framework для SQL Server кэширует результаты sys.sp_describe_parameter_encryption для каждой инструкции запроса. Таким образом, если одна и та же инструкция запроса выполняется несколько раз, драйвер вызывает sys.sp_describe_parameter_encryption всего один раз. Кэширование метаданных шифрования для инструкций запроса значительно сокращает затраты ресурсов на получение метаданных из базы данных. Кэширование включено по умолчанию. Можно отключить параметр кэширования метаданных, задав для SqlConnection.ColumnEncryptionQueryMetadataCacheEnabled свойство значение false, однако рекомендуется делать это только в редких случаях, например в описанной ниже ситуации:

Рассмотрим базу данных с двумя схемами s1 и s2. Каждая из этих схем содержит таблицу с именем t. Определения таблиц s1.t и s2.t идентичны, за исключением свойств, связанных с шифрованием: столбец c в таблице s1.t не шифруется, однако зашифрован в таблице s2.t. База данных имеет двух пользователей: u1 и u2. Схема по умолчанию для пользователей u1s1. Для u2 указана схема по умолчанию s2. Приложение .NET открывает два подключения к базе данных, олицетворяя пользователя u1 в одном из них и пользователя u2 в другом. Приложение отправляет запрос с параметром, нацеленным на столбец c, по соединению от имени пользователя u1 (в запросе не указана схема, поэтому используется пользовательская схема по умолчанию). Затем приложение отправляет тот же запрос через подключение для пользователя u2. Если кэширование метаданных запроса включено, после первого запроса кэш будет заполнен метаданными, указывающими c на столбец, целевые объекты параметров запроса не шифруются. Поскольку второй запрос имеет тот же текст запроса, будет использована информация, хранящаяся в кэше. В результате драйвер отправит запрос без шифрования параметра (неправильного, так как целевой столбец s2.t.c зашифрован), утечки значения открытого текста параметра на сервер. Сервер обнаружит несоответствие и велит драйверу обновить кэш, чтобы приложение могло прозрачно переотправить запрос с правильно зашифрованным значением параметра. В этом случае следует отключить кэширование во избежание утечки конфиденциальных значений на сервер.

Настройка Always Encrypted на уровне запроса

Для управления влиянием процесса получения метаданных шифрования для параметризованных запросов на производительность можно включить постоянное шифрование для отдельных запросов, а не настраивать его для соединения. Таким образом, это гарантирует, что sys.sp_describe_parameter_encryption вызывается только для запросов, которые точно имеют параметры, предназначенные для зашифрованных столбцов. Обратите внимание, что в этом случае снижается прозрачность шифрования: при изменении свойств шифрования столбцов базы данных может потребоваться изменить код приложения в соответствии с изменениями схемы.

Примечание.

Настройка Always Encrypted на уровне запроса дает ограниченный выигрыш в производительности для платформы .NET 4.6.2 и более поздних версий, где реализовано кэширование метаданных шифрования параметра.

Для управления поведением функции Always Encrypted в отдельных запросах необходимо использовать этот конструктор SqlCommand и SqlCommandColumnEncryptionSetting. Ниже приведены некоторые полезные рекомендации.

  • Если большинство запросов, которые клиентское приложение отправляет через подключение к базе данных, обращаются к зашифрованным столбцам:
    • Задайте для ключевого слова строки подключения Column Encryption Setting значение Enabled.
    • Задайте sqlCommandColumnEncryptionSetting.Disabled для отдельных запросов, которые не обращаются к зашифрованным столбцам. В этом варианте отключается возможность вызова sys.sp_describe_parameter_encryption и расшифровки значений в наборе результатов.
    • Задайте sqlCommandColumnEncryptionSetting.ResultSet для отдельных запросов, которые не имеют параметров, требующих шифрования, но извлеките данные из зашифрованных столбцов. В этом варианте отключается возможность вызова sys.sp_describe_parameter_encryption и шифрования параметров. Запрос сможет расшифровывать результаты из столбцов шифрования.
  • Если большинство запросов, которые клиентское приложение отправляет через подключение к базе данных, не обращается к зашифрованным столбцам:
    • Задайте для ключевого слова строки подключения Column Encryption Setting значение Disabled.
    • Задайте SqlCommandColumnEncryptionSetting.Enabled для отдельных запросов, имеющих параметры, которые требуется зашифровать. В этом варианте включается возможность вызова sys.sp_describe_parameter_encryption и расшифровки результатов запроса, полученных из зашифрованных столбцов.
    • Задайте SqlCommandColumnEncryptionSetting.ResultSet для запросов, которые не имеют параметров, требующих шифрования, но получают данные из зашифрованных столбцов. В этом варианте отключается возможность вызова sys.sp_describe_parameter_encryption и шифрования параметров. Запрос сможет расшифровывать результаты из столбцов шифрования.

В следующем примере постоянное шифрование отключено для подключения к базе данных. Запрос, который возникает в приложении, имеет параметр, предназначенный для столбца LastName, который не зашифрован. Запрос получает данные из зашифрованных столбцов SSN и BirthDate. В этом случае вызывать sys.sp_describe_parameter_encryption для получения метаданных шифрования не требуется. Однако необходимо включить расшифровку результатов запроса, чтобы приложение могло получать значения в виде обычного текста из двух зашифрованных столбцов. Для этого используется параметр SqlCommandColumnEncryptionSetting.ResultSet.

string connectionString = "Data Source=server63; Initial Catalog=Clinic; Integrated Security=true";
using (SqlConnection connection = new SqlConnection(connectionString))
{
    connection.Open();
    using (SqlCommand cmd = new SqlCommand(@"SELECT [SSN], [FirstName], [LastName], [BirthDate] FROM [dbo].[Patients] WHERE [LastName]=@LastName",
connection, null, SqlCommandColumnEncryptionSetting.ResultSetOnly))
    {
        SqlParameter paramLastName = cmd.CreateParameter();
        paramLastName.ParameterName = @"@LastName";
        paramLastName.DbType = DbType.String;
        paramLastName.Direction = ParameterDirection.Input;
        paramLastName.Value = "Abel";
        paramLastName.Size = 50;
        cmd.Parameters.Add(paramLastName);
        using (SqlDataReader reader = cmd.ExecuteReader())
            {
               if (reader.HasRows)
               {
                  while (reader.Read())
                  {
                     Console.WriteLine(@"{0}, {1}, {2}, {3}", reader[0], reader[1], reader[2], ((DateTime)reader[3]).ToShortDateString());
                  }
               }
            }
  } 
}

Кэширование ключа шифрования столбца

Чтобы уменьшить количество вызовов к хранилищу главных ключей столбцов для расшифровки ключей шифрования столбцов, поставщик данных .NET Framework для SQL Server кэширует ключи шифрования столбцов с открытым текстом в памяти. После получения значения ключа шифрования зашифрованного столбца метаданных базы данных драйвер сначала пытается найти ключ шифрования столбца с открытым текстом, соответствующий зашифрованному значению ключа. Драйвер вызывает хранилище ключей, содержащее главный ключ столбца, только если он не может найти значение ключа шифрования зашифрованного столбца в кэше.

Примечание.

В платформе .NET Framework 4.6 и 4.6.1 записи ключей шифрования столбцов в кэше никогда не удаляются. Это означает, что для данного ключа шифрования зашифрованного столбца драйвер обращается в хранилище ключей только один раз за все время существования приложения.

В платформе .NET Framework 4.6.2 и более поздних версий записи кэша удаляются по истечении настроенного срока жизни из соображений безопасности. Значение времени жизни (TTL) по умолчанию составляет 2 часа. Если у вас действуют более строгие требования к безопасности, касающиеся времени кэширования ключей шифрования столбца в виде открытого текста в приложении, это значение можно изменить с помощью свойства SqlConnection.ColumnEncryptionKeyCacheTtl.

Включение дополнительной защиты для скомпрометированного SQL Server

По умолчанию поставщик данных .NET Framework для SQL Server полагается на систему базы данных (SQL Server или Базу данных SQL Azure), которая предоставляет метаданные о том, какие столбцы базы данных шифруются и как именно. Метаданные шифрования позволяют поставщику данных .NET Framework для SQL Server шифровать параметры запроса и расшифровывать результаты запроса без получения дополнительных входных данных из приложения, что позволяет значительно сократить число изменений, необходимых для приложения. Однако если процесс SQL Server скомпрометирован и злоумышленник незаконно изменяет метаданные, которые SQL Server отправляет поставщику данных платформы .NET Framework для SQL Server, злоумышленник получает возможность украсть конфиденциальную информацию. В этом разделе описываются API-интерфейсы, которые помогают обеспечить дополнительный уровень защиты от таких атак за счет снижения прозрачности.

Принудительное шифрование параметров

Прежде чем поставщик данных .NET Framework для SQL Server отправляет параметризованный запрос в SQL Server, он просит SQL Server (путем вызова sys.sp_describe_parameter_encryption) проанализировать инструкцию запроса и предоставить сведения о том, какие параметры запроса должны быть зашифрованы. Скомпрометированный экземпляр SQL Server может ввести в заблуждение поставщик данных .NET Framework для SQL Server, отправив метаданные, указывающие на то, что параметр не относится к зашифрованному столбцу, хотя в базе данных этот столбец зашифрован. В результате поставщик данных платформа .NET Framework для SQL Server не зашифрует значение параметра, и он отправит его в виде обычного текста в скомпрометированный экземпляр SQL Server.

Чтобы предотвратить подобную атаку, приложение может присвоить свойству SqlParameter.ForceColumnEncryption для параметра значение true. Это приведет к тому, что поставщик данных платформа .NET Framework для SQL Server выдает исключение, если метаданные, полученные от сервера, указывают на то, что параметр не требует шифрования.

Хотя использование свойства SqlParameter.ForceColumnEncryption помогает повысить безопасность, оно также снижает прозрачность шифрования для клиентского приложения. Если вы обновляете схему базы данных для изменения набора зашифрованных столбцов, вам может потребоваться изменить и само приложение.

В следующем примере кода показано, как с помощью свойства SqlParameter.ForceColumnEncryption предотвратить отправку номеров социального страхования в базу данных в формате открытого текста.

SqlCommand cmd = _sqlconn.CreateCommand(); 

// Use parameterized queries to access Always Encrypted data. 
 
cmd.CommandText = @"SELECT [SSN], [FirstName], [LastName], [BirthDate] FROM [dbo].[Patients] WHERE [SSN] = @SSN;"; 

SqlParameter paramSSN = cmd.CreateParameter(); 
paramSSN.ParameterName = @"@SSN"; 
paramSSN.DbType = DbType.AnsiStringFixedLength; 
paramSSN.Direction = ParameterDirection.Input; 
paramSSN.Value = ssn; 
paramSSN.Size = 11; 
paramSSN.ForceColumnEncryption = true; 
cmd.Parameters.Add(paramSSN); 

SqlDataReader reader = cmd.ExecuteReader();

Настройка доверенных путей главного ключа столбца

Метаданные шифрования, возвращаемые SQL Server для параметров запроса, предназначенных для зашифрованных столбцов, и результатов, полученных из зашифрованных столбцов, включают в себя путь к главному ключу столбца, определяющий хранилище ключей и расположение ключа в этом хранилище. Если экземпляр SQL Server скомпрометирован, он может передать путь к ключу, который направит .NET Framework Data Provider for SQL Server в местоположение, контролируемое злоумышленником. Это может привести к утечке учетных данных хранилища ключей в случае, если хранилище ключей требует аутентификации приложения.

Для предотвращения подобных атак приложение может задать список доверенных путей для отдельного сервера с помощью свойства SqlConnection.ColumnEncryptionTrustedMasterKeyPaths. Если поставщик данных платформы .NET для SQL Server получает путь к ключу, который не входит в список доверенных путей к ключам, он создает исключение.

Хотя настройка доверенных путей к ключам повышает безопасность вашего приложения, вам потребуется изменить код и/или конфигурацию приложения каждый раз при ротации главного ключа столбца (то есть при изменении пути к главному ключу столбца).

В следующем примере показано, как настроить доверенные пути к главному ключу столбца:

// Configure trusted key paths to protect against fake key paths sent by a compromised SQL Server instance 
// First, create a list of trusted key paths for your server 
List<string> trustedKeyPathList = new List<string>(); 
trustedKeyPathList.Add("CurrentUser/my/425CFBB9DDDD081BB0061534CE6AB06CB5283F5Ea"); 

// Register the trusted key path list for your server 

SqlConnection.ColumnEncryptionTrustedMasterKeyPaths.Add(serverName, trustedKeyPathList);

Копирование зашифрованных данных с помощью SqlBulkCopy

С помощью SqlBulkCopy можно скопировать данные, которые уже зашифрованы и хранятся в одной таблице, в другую таблицу, не расшифровывая при этом данные. Для этого выполните указанные далее действия.

  • Убедитесь, что конфигурация шифрования целевой таблицы идентична конфигурации исходной таблицы. В частности, обе таблицы должны иметь одинаковые зашифрованные столбцы, которые должны быть зашифрованы с помощью одних и тех же типов шифрования и ключей шифрования. Примечание. Если любой из целевых столбцов шифруется не так, как соответствующий исходный столбец, вы не сможете расшифровать данные в целевой таблице после операции копирования. Данные будут повреждены.
  • Настройте подключения базы данных к исходной и целевой таблицам без включения постоянного шифрования.
  • Задайте параметр AllowEncryptedValueModifications (см. раздел SqlBulkCopyOptions). Примечание. Используйте осторожность при указании AllowEncryptedValueModifications, так как это может привести к повреждению базы данных, так как поставщик данных платформа .NET Framework для SQL Server не проверяет, зашифрованы ли данные действительно или правильно зашифрованы с использованием того же типа шифрования, алгоритма и ключа, что и целевой столбец.

Параметр AllowEncryptedValueModifications доступен в .NET Framework 4.6.1 и более поздних версиях.

Ниже приведен пример копирования данных из одной таблицы в другую. Предполагается, что столбцы SSN и BirthDate зашифрованы.

static public void CopyTablesUsingBulk(string sourceTable, string targetTable)
{
   string sourceConnectionString = "Data Source=server63; Initial Catalog=Clinic; Integrated Security=true";
   string targetConnectionString = "Data Source= server64; Initial Catalog=Clinic; Integrated Security=true";
   using (SqlConnection connSource = new SqlConnection(sourceConnectionString))
   {
      connSource.Open();
      using (SqlCommand cmd = new SqlCommand(string.Format("SELECT [PatientID], [SSN], [FirstName], [LastName], [BirthDate] FROM {0}", sourceTable), connSource))
      {
         using (SqlDataReader reader = cmd.ExecuteReader())
         {
            SqlBulkCopy copy = new SqlBulkCopy(targetConnectionString, SqlBulkCopyOptions.KeepIdentity | SqlBulkCopyOptions.AllowEncryptedValueModifications);
            copy.EnableStreaming = true;
            copy.DestinationTableName = targetTable;
            copy.WriteToServer(reader);
         }
      }
}

Справочник по API Always Encrypted

Пространство имен:System.Data.SqlClient

Сборка: System.Data (в файле System.Data.dll)

Имя Описание Добавлено в версии .NET
Класс SqlColumnEncryptionCertificateStoreProvider Поставщик хранилища ключей для хранилища сертификатов Windows. 4,6
Класс SqlColumnEncryptionCngProvider Поставщик хранилища ключей для интерфейса Microsoft Cryptography API: Next Generation (CNG). 4.6.1
Класс SqlColumnEncryptionCspProvider Поставщик хранилища ключей для поставщиков криптографических услуг (CSP), основанных на Microsoft CAPI. 4.6.1
Класс SqlColumnEncryptionKeyStoreProvider Базовый класс для поставщиков хранилищ ключей. 4,6
Перечисление SqlCommandColumnEncryptionSetting Параметры для включения шифрования и расшифровки для подключения к базе данных. 4,6
Перечисление SqlConnectionColumnEncryptionSetting Параметры для управления поведением постоянного шифрования для отдельных запросов. 4,6
Свойство SqlConnectionStringBuilder.ColumnEncryptionSetting Возвращает или задает Always Encrypted в строке подключения. 4,6
Свойство SqlConnection.ColumnEncryptionQueryMetadataCacheEnabled Включает и отключает кэширование метаданных для запроса шифрования. 4.6.2
Свойство SqlConnection.ColumnEncryptionKeyCacheTtl Возвращает и задает срок жизни для записей в кэше ключа шифрования столбца. 4.6.2
Свойство SqlConnection.ColumnEncryptionTrustedMasterKeyPaths Позволяет задать список доверенных путей ключа для сервера базы данных. Если при обработке запроса приложения драйвер получает путь ключа, которого нет в списке, произойдет сбой запроса. Это свойство обеспечивает дополнительную защиту от атак на систему безопасности, включающих предоставление скомпрометированным SQL Server фиктивных путей ключа, что может привести к утечке учетных данных хранилища ключей. 4,6
Метод SqlConnection.RegisterColumnEncryptionKeyStoreProviders Позволяет регистрировать пользовательские поставщики хранилища ключей. Это словарь, сопоставляющий имена поставщиков хранилища ключей с реализациями поставщиков хранилища ключей. 4,6
Конструктор SqlCommand (String, SqlConnection, SqlTransaction, SqlCommandColumnEncryptionSetting) Позволяет управлять поведением постоянного шифрования для отдельных запросов. 4,6
Свойство SqlParameter.ForceColumnEncryption Принудительно шифрует параметр. Если SQL Server сообщает драйверу, что шифровать параметр необязательно, произойдет сбой запроса, использующего этот параметр. Это свойство обеспечивает дополнительную защиту от атак на систему безопасности, включающих предоставление клиенту скомпрометированным SQL Server неверных метаданных шифрования, что может привести к раскрытию данных. 4,6
Новое ключевое слово в строке подключения: Column Encryption Setting=enabled Включает или отключает функцию постоянного шифрования для подключения. 4,6

См. также