Использование функции Always Encrypted с драйвером ODBC для SQL ServerUsing Always Encrypted with the ODBC Driver for SQL Server

СкачатьСкачать драйвер ODBCDownloadDownload ODBC Driver

Применимо кApplicable to

  • ODBC Driver for SQL Server версии 13.1ODBC Driver 13.1 for SQL Server
  • ODBC Driver for SQL Server версии 17ODBC Driver 17 for SQL Server

ВведениеIntroduction

В этой статье содержатся сведения о разработке приложений ODBC с помощью Always Encrypted (ядро СУБД) или Always Encrypted с безопасными анклавами и ODBC Driver for SQL Server.This article provides information on how to develop ODBC applications using Always Encrypted (Database Engine) or Always Encrypted with Secure Enclaves and the ODBC Driver for SQL Server.

Функция Always Encrypted позволяет шифровать конфиденциальные данные в клиентских приложениях, не раскрывая данные или ключи шифрования для SQL Server или Базы данных SQL Azure.Always Encrypted allows client applications to encrypt sensitive data and never reveal the data or the encryption keys to SQL Server or Azure SQL Database. Драйвер с поддержкой Always Encrypted, такой как драйвер OLE DB для SQL Server, реализует это за счет прозрачного шифрования и расшифровки конфиденциальных данных в клиентском приложении.An Always Encrypted enabled driver, such as the ODBC Driver for SQL Server, achieves this by transparently encrypting and decrypting sensitive data in the client application. Драйвер автоматически определяет, какие параметры запроса соответствуют важным столбцам базы данных (защищенным с помощью Always Encrypted), и шифрует значения этих параметров перед передачей данных в SQL Server или Базу данных SQL Azure.The driver automatically determines which query parameters correspond to sensitive database columns (protected using Always Encrypted), and encrypts the values of those parameters before passing the data to SQL Server or Azure SQL Database. Аналогичным образом драйвер прозрачно расшифровывает данные, полученные из зашифрованных столбцов базы в результатах запроса.Similarly, the driver transparently decrypts data retrieved from encrypted database columns in query results. Always Encrypted с безопасными анклавами обеспечивает расширенные функции защиты конфиденциальных данных.Always Encrypted with secure enclaves extends this feature to enable richer functionality on sensitive data while keeping the data confidential.

Дополнительные сведения см. в разделе Always encrypted (ядро СУБД) и Always encrypted с помощью Secure енклавес.For more information, see Always Encrypted (Database Engine) and Always Encrypted with Secure Enclaves.

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

Настройте функцию постоянного шифрования в базе данных.Configure Always Encrypted in your database. В процесс настройки входят действия по подготовке ключей постоянного шифрования и настройке шифрования для выбранных столбцов базы данных.This involves provisioning Always Encrypted keys and setting up encryption for selected database columns. Если в базе данных постоянное шифрование еще не настроено, следуйте инструкциям в разделе Приступая к работе с постоянным шифрованием.If you do not already have a database with Always Encrypted configured, follow the directions in Getting Started with Always Encrypted. В частности база данных должна содержать определения метаданных для главного ключа столбца (CMK), ключа шифрования столбца (CEK) и таблицы с одним или несколькими столбцами, зашифрованными с помощью этого ключа CEK.In particular, your database should contain the metadata definitions for a Column Master Key (CMK), a Column Encryption Key (CEK), and a table containing one or more columns encrypted using that CEK.

Включение Always Encrypted в приложении ODBCEnabling Always Encrypted in an ODBC Application

Самым простым способом одновременно включить шифрование параметров и расшифровку столбца с зашифрованным набором результатов будет установка значения Enabled для ключевого слова строки подключения ColumnEncryption.The easiest way to enable both parameter encryption and resultset encrypted column decryption is by setting the value of the ColumnEncryption connection string keyword to Enabled. Ниже приведен пример строки подключения, включающей Always Encrypted.The following is an example of a connection string which enables Always Encrypted:

SQLWCHAR *connString = L"Driver={ODBC Driver 13 for SQL Server};Server={myServer};Trusted_Connection=yes;ColumnEncryption=Enabled;";

Always Encrypted также можно включить в конфигурации имени DSN, используя тот же ключ и значение (которое переопределяется параметром строки подключения, если он указан), или указать программно с помощью атрибута предварительного подключения SQL_COPT_SS_COLUMN_ENCRYPTION.Always Encrypted may also be enabled in the DSN configuration, using the same key and value (which will be overridden by the connection string setting, if present), or programmatically with the SQL_COPT_SS_COLUMN_ENCRYPTION pre-connection attribute. Такая настройка переопределяет значение, указанное в строке подключения или имени DSN:Setting it this way overrides the value set in the connection string or DSN:

 SQLSetConnectAttr(hdbc, SQL_COPT_SS_COLUMN_ENCRYPTION, (SQLPOINTER)SQL_COLUMN_ENCRYPTION_ENABLE, 0);

Включив Always Encrypted для подключения, вы можете изменять его поведение для отдельных запросов.Once enabled for the connection, the behavior of Always Encrypted may be adjusted for individual queries. Подробнее см. раздел Управление влиянием Always Encrypted на производительность ниже.See Controlling the Performance Impact of Always Encrypted below for more information.

Обратите внимание, что включенной функции Always Encrypted недостаточно для успешного шифрования или расшифровки, вам нужно выполнить еще и следующие условия.Note that enabling Always Encrypted is not sufficient for encryption or decryption to succeed; you also need to make sure that:

  • Приложение имеет разрешения VIEW ANY COLUMN MASTER KEY DEFINITION и VIEW ANY COLUMN ENCRYPTION KEY DEFINITION для базы данных, необходимые для доступа к метаданным о ключах постоянного шифрования в базе данных.The application has the VIEW ANY COLUMN MASTER KEY DEFINITION and VIEW ANY COLUMN ENCRYPTION KEY DEFINITION database permissions, required to access the metadata about Always Encrypted keys in the database. Дополнительные сведения см. в описании разрешений базы данных.For details, see Database Permissions.

  • Приложение может обращаться к CMK, который защищает ключи CEK для запрашиваемых зашифрованных столбцов.The application can access the CMK which protects the CEKs for the queried encrypted columns. Это поведение зависит от поставщика хранилища ключей, который хранит CMK.This is dependent on the keystore provider which stores the CMK. Подробнее см. в разделе Работа с хранилищами главных ключей столбцов.See Working with Column Master Key Stores for more information.

Включение Always Encrypted с безопасными анклавамиEnabling Always Encrypted with Secure Enclaves

Начиная с версии 17.4 драйвер поддерживает Always Encrypted с безопасными анклавами.Beginning with version 17.4, the driver supports Always Encrypted with Secure Enclaves. Чтобы включить использование анклава при подключении к SQL Server 2019 или более поздней версии, задайте ColumnEncryption имя DSN, строку подключения или атрибут соединения с именем типа анклава и протоколом аттестации, а также связанные данные аттестации, разделенные запятыми.To enable use of the enclave when connecting to SQL Server 2019 or later, set the ColumnEncryption DSN, connection string, or connection attribute to the name of the enclave type and attestation protocol, and associated attestation data, separated by a comma. В версии 17,4 поддерживается только анклава типа безопасности на основе виртуализации и протокол аттестации службы защиты узла , обозначенный VBS-HGS. чтобы использовать его, укажите URL-адрес сервера аттестации, например:In version 17.4, only the Virtualization Based Security enclave type and Host Guardian Service attestation protocol, denoted by VBS-HGS, is supported; to use it, specify the URL of the attestation server, for example:

Driver=ODBC Driver 17 for SQL Server;Server=yourserver.yourdomain;Trusted_Connection=Yes;ColumnEncryption=VBS-HGS,http://attestationserver.yourdomain/Attestation

Если сервер и служба аттестации настроены правильно, а также анклава ключей CMK и Цекс для нужных столбцов, то теперь вы сможете выполнять запросы, использующие анклава, например шифрование на месте и расширенные вычисления, в дополнение к существующие функциональные возможности, предоставляемые Always Encrypted.If the server and attestation service are configured correctly, as well as enclave-enabled CMKs and CEKs for the desired columns, you should now be able to execute queries which use the enclave such as in-place encryption and rich computations, in addition to the existing functionality provided by Always Encrypted. Дополнительные сведения см. в статье настройка Always encrypted с помощью Secure енклавес .See Configure Always Encrypted with secure enclaves for more information.

Получение и изменение данных в зашифрованных столбцахRetrieving and Modifying Data in Encrypted Columns

После включения Always Encrypted для подключения можно использовать стандартные API-интерфейсы ODBC.Once you enable Always Encrypted on a connection, you can use standard ODBC APIs. API-интерфейсы ODBC могут извлекать или изменять данные в зашифрованных столбцах базы данных.The ODBC APIs can retrieve or modify data in encrypted database columns. Следующие элементы документации могут помочь в этом:The following documentation items might help with this:

Приложение должно иметь необходимые разрешения базы данных и иметь возможность доступа к главному ключу столбца.Your application must have the required database permissions, and must be able to access the column master key. Затем драйвер шифрует все параметры запроса, предназначенные для зашифрованных столбцов.Then, the driver encrypts any query parameters that target encrypted columns. Драйвер также расшифровывает данные, полученные из зашифрованных столбцов.The driver also decrypts data retrieved from encrypted columns. Драйвер выполняет все эти шифрование и расшифровку без помощи в исходном коде.The driver performs all this encrypting and decrypting without any assistance from your source code. Для программы это так, как если бы столбцы не были зашифрованы.To your program, it is as if the columns are not encrypted.

Если функция Always Encrypted не включена, выполнение запросов с параметрами, предназначенными для зашифрованных столбцов, завершается ошибкой.If Always Encrypted is not enabled, queries with parameters which target encrypted columns will fail. Данные по-прежнему могут извлекаться из зашифрованных столбцов, пока для них не будут указаны параметры, предназначенные для зашифрованных столбцов.Data can still be retrieved from encrypted columns, as long as the query has no parameters targeting encrypted columns. Однако драйвер не будет применять расшифровку, и приложение будет получать двоичные зашифрованные данные (в виде массивов байтов).However, the driver will not attempt any decryption and the application will receive the binary encrypted data (as byte arrays).

В приведенной ниже таблице описывается поведение запросов в зависимости от того, включена функция Always Encrypted или нет.The table below summarizes the behavior of queries, depending on whether Always Encrypted is enabled or not:

Характеристика запросаQuery characteristic Постоянное шифрование включено, и приложение может получать доступ к ключам и метаданным ключейAlways Encrypted is enabled and application can access the keys and key metadata Постоянное шифрование включено, и приложение не может получать доступ к ключам и метаданным ключейAlways Encrypted is enabled and application cannot access the keys or key metadata Постоянное шифрование отключеноAlways Encrypted is disabled
Параметры, предназначенные для зашифрованных столбцов.Parameters targeting encrypted columns. Значения параметров прозрачно шифруются.Parameter values are transparently encrypted. ОшибкаError ОшибкаError
Извлечение данных из зашифрованных столбцов без параметров, предназначенных для зашифрованных столбцов.Retrieving data from encrypted columns, without parameters targeting encrypted columns. Результаты из зашифрованных столбцов прозрачно расшифровываются.Results from encrypted columns are transparently decrypted. Приложение получает значения столбца в виде обычного текста.The application receives plaintext column values. ОшибкаError Результаты из зашифрованных столбцов не расшифровываются.Results from encrypted columns are not decrypted. Приложение получает зашифрованные значения в виде массивов байтов.The application receives encrypted values as byte arrays.

В следующих примерах показано получение и изменение данных в зашифрованных столбцах.The following examples illustrate retrieving and modifying data in encrypted columns. В этом примере предполагается, что таблица имеет следующую схему.The examples assume a table with the following schema. Обратите внимание, что столбцы SSN и BirthDate зашифрованы.Note that the SSN and BirthDate columns are encrypted.

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

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

В этом примере показана вставка строки в таблицу Patients.This example inserts a row into the Patients table. Следует отметить следующее.Note the following:

  • В образце кода нет ничего, связанного с шифрованием.There is nothing specific to encryption in the sample code. Драйвер автоматически обнаруживает и шифрует значения параметров SSN и даты, которые предназначены зашифрованных столбцов.The driver automatically detects and encrypts the values of the SSN and date parameters, which target encrypted columns. В этом случае шифрование является прозрачным для приложения.This makes encryption transparent to the application.

  • Данные, вставленные в столбцы базы данных (в том числе в зашифрованные) передаются в качестве привязанных параметров (см. Функция SQLBindParameter).The values inserted into database columns, including the encrypted columns, are passed as bound parameters (see SQLBindParameter Function). Несмотря на то, что при отправке значений в незашифрованные столбцы использовать параметры необязательно (но настоятельно рекомендуется, так как это помогает предотвратить внедрение кода SQL), они требуются для значений, предназначенных для зашифрованных столбцов.While using parameters is optional when sending values to non-encrypted columns (although it is highly recommended because it helps prevent SQL injection), it is required for values targeting encrypted columns. Если значения, вставленные в столбцы SSN или BirthDate, были переданы в качестве внедренных в инструкцию запроса литералов, выполнение запроса завершится ошибкой, так как драйвер не пытается шифровать или иным образом обрабатывать литералы в запросах.If the values inserted in the SSN or BirthDate columns were passed as literals embedded in the query statement, the query would fail because the driver does not attempt to encrypt or otherwise process literals in queries. В результате сервер отклонит их как несовместимые с зашифрованными столбцами.As a result, the server would reject them as incompatible with the encrypted columns.

  • Для параметров, вставляемых в столбец SSN, устанавливается тип SQL SQL_CHAR, который сопоставляется с типом данных SQL Server char (rc = SQLBindParameter(hstmt, 1, SQL_PARAM_INPUT, SQL_C_CHAR, SQL_CHAR, 11, 0, (SQLPOINTER)SSN, 0, &cbSSN);).The SQL type of the parameter inserted into the SSN column is set to SQL_CHAR, which maps to the char SQL Server data type (rc = SQLBindParameter(hstmt, 1, SQL_PARAM_INPUT, SQL_C_CHAR, SQL_CHAR, 11, 0, (SQLPOINTER)SSN, 0, &cbSSN);). Если для параметра был задан тип SQL_WCHAR, который сопоставляется с типом данных nchar, выполнение запроса завершится ошибкой, так как Always Encrypted не поддерживает преобразования на стороне сервера из зашифрованных значений nchar в зашифрованные значения char.If the type of the parameter was set to SQL_WCHAR, which maps to nchar, the query would fail, as Always Encrypted does not support server-side conversions from encrypted nchar values to encrypted char values. Сведения о сопоставлении типов данных см. в этом приложении справочника по программированию ODBC о типах данных.See ODBC Programmer's Reference -- Appendix D: Data Types for information about the data type mappings.

    SQL_DATE_STRUCT date;
    SQLLEN cbdate;   // size of date structure  

    SQLCHAR SSN[12];
    strcpy_s((char*)SSN, _countof(SSN), "795-73-9838");

    SQLWCHAR* firstName = L"Catherine";
    SQLWCHAR* lastName = L"Abel";
    SQLINTEGER cbSSN = SQL_NTS, cbFirstName = SQL_NTS, cbLastName = SQL_NTS;

    // Initialize the date structure  
    date.day = 10;
    date.month = 9;
    date.year = 1996;

    // Size of structures   
    cbdate = sizeof(SQL_DATE_STRUCT);

    SQLRETURN rc = 0;

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

    rc = SQLPrepare(hstmt, (SQLCHAR *)queryText.c_str(), SQL_NTS);

    //SSN
    rc = SQLBindParameter(hstmt, 1, SQL_PARAM_INPUT, SQL_C_CHAR, SQL_CHAR, 11, 0, (SQLPOINTER)SSN, 0, &cbSSN);
    //FirstName
    rc = SQLBindParameter(hstmt, 2, SQL_PARAM_INPUT, SQL_C_WCHAR, SQL_WCHAR, 50, 0, (SQLPOINTER)firstName, 0, &cbFirstName);
    //LastName
    rc = SQLBindParameter(hstmt, 3, SQL_PARAM_INPUT, SQL_C_WCHAR, SQL_WCHAR, 50, 0, (SQLPOINTER)lastName, 0, &cbLastName);
    //BirthDate
    rc = SQLBindParameter(hstmt, 4, SQL_PARAM_INPUT, SQL_C_TYPE_DATE, SQL_TYPE_DATE, 10, 0, (SQLPOINTER)&date, 0, &cbdate);

    rc = SQLExecute(hstmt);

Пример получения данных в виде открытого текстаPlaintext Data Retrieval Example

В следующем примере показана фильтрация данных на основе зашифрованных значений и получение данных в виде открытого текста из зашифрованных столбцов.The following example demonstrates filtering data based on encrypted values, and retrieving plaintext data from encrypted columns. Следует отметить следующее.Note the following:

  • Значение, используемое в предложении WHERE для фильтрации по столбцу SSN, необходимо передавать, используя SQLBindParameter, чтобы перед отправкой на сервер драйвер мог его прозрачно зашифровать.The value used in the WHERE clause to filter on the SSN column needs to be passed using SQLBindParameter, so that the driver can transparently encrypt it before sending it to the server.

  • Все значения, выводимые программой, будут представлены в виде обычного текста, так как драйвер прозрачно расшифрует данные, полученные из столбцов SSN и BirthDate.All values printed by the program will be in plaintext, since the driver will transparently decrypt the data retrieved from the SSN and BirthDate columns.

Примечание

Запросы могут выполнять сравнения на равенство в зашифрованных столбцах только в том случае, если шифрование является детерминированным или включен безопасный анклава.Queries can perform equality comparisons on encrypted columns only if the encryption is deterministic, or if the secure enclave is enabled. Дополнительные сведения см. в разделе Выбор детерминированного или случайного шифрования.For more information, see Selecting Deterministic or Randomized encryption.

SQLCHAR SSN[12];
strcpy_s((char*)SSN, _countof(SSN), "795-73-9838");

SQLWCHAR* firstName = L"Catherine";
SQLWCHAR* lastName = L"Abel";
SQLINTEGER cbSSN = SQL_NTS, cbFirstName = SQL_NTS, cbLastName = SQL_NTS;

SQLRETURN rc = 0;
string empty = "";
string queryText = "SELECT [SSN], [FirstName], [LastName], [BirthDate] " + empty +
    "FROM  [dbo].[Patients]" +
    "WHERE " +
    "[SSN] = ? ";

rc = SQLPrepare(hstmt, (SQLCHAR *)queryText.c_str(), SQL_NTS);

//SSN
rc = SQLBindParameter(hstmt, 1, SQL_PARAM_INPUT, SQL_C_CHAR, SQL_CHAR, 11, 0, (SQLPOINTER)SSN, 0, &cbSSN);

rc = SQLExecute(hstmt);
HandleDiagnosticRecord(hstmt, SQL_HANDLE_STMT, rc);

SQL_DATE_STRUCT dateVal;
SQLWCHAR firstNameVal[50];
SQLWCHAR lastNameVal[50];
SQLCHAR SSNVal[12];
SQLLEN cbdate;   // size of date structure  

int rowcount = 0;
while (SQL_SUCCEEDED(SQLFetch(hstmt)))
{
    rowcount++;
    SQLGetData(hstmt, 1, SQL_C_CHAR, &SSNVal, 11, &cbSSN);
    SQLGetData(hstmt, 2, SQL_C_WCHAR, &firstNameVal, 50, &cbFirstName);
    SQLGetData(hstmt, 3, SQL_C_WCHAR, &lastNameVal, 50, &cbLastName);
    SQLGetData(hstmt, 4, SQL_C_TYPE_DATE, &dateVal, 10, &cbdate);        
}

Пример получения данных в виде зашифрованного текстаCiphertext Data Retrieval Example

Если постоянное шифрование не включено, запрос может получать данные из зашифрованных столбцов, пока для него не будут указаны параметры, предназначенные для зашифрованных столбцов.If Always Encrypted is not enabled, a query can still retrieve data from encrypted columns, as long as the query has no parameters targeting encrypted columns.

В приведенном ниже примере показано извлечение двоичных зашифрованных данных из зашифрованных столбцов.The following example illustrates retrieving binary encrypted data from encrypted columns. Следует отметить следующее.Note the following:

  • Так как постоянное шифрование не включено в строке подключения, запрос будет возвращать зашифрованные значения SSN и BirthD в виде байтовых массивов (программа преобразует значения в строки).As Always Encrypted is not enabled in the connection string, the query will return encrypted values of SSN and BirthDate as byte arrays (the program converts the values to strings).
  • Запрос, получающий данные из зашифрованных столбцов с отключенным постоянным шифрованием, может иметь параметры при условии, что ни один из параметров не предназначен для зашифрованного столбца.A query retrieving data from encrypted columns with Always Encrypted disabled can have parameters, as long as none of the parameters target an encrypted column. Приведенный выше запрос выполняет фильтрацию по LastName, который не зашифрован в базе данных.The above query filters by LastName, which is not encrypted in the database. Запрос, отфильтрованный по SSN или BirthDate, завершится ошибкой.If the query filtered by SSN or BirthDate, the query would fail.
SQLCHAR SSN[12];
strcpy_s((char*)SSN, _countof(SSN), "795-73-9838");

SQLWCHAR* firstName = L"Catherine";
SQLWCHAR* lastName = L"Abel";
SQLINTEGER cbSSN = SQL_NTS, cbFirstName = SQL_NTS, cbLastName = SQL_NTS;

SQLRETURN rc = 0;
string empty = "";
string queryText = "SELECT [SSN], [FirstName], [LastName], [BirthDate] " + empty +
    "FROM  [dbo].[Patients]" +
    "WHERE " +
    "[LastName] = ?";

rc = SQLPrepare(hstmt, (SQLCHAR *)queryText.c_str(), SQL_NTS);

//LastName
rc = SQLBindParameter(hstmt, 1, SQL_PARAM_INPUT, SQL_C_WCHAR, SQL_WCHAR, 50, 0, (SQLPOINTER)lastName, 0, &cbLastName);

rc = SQLExecute(hstmt);
HandleDiagnosticRecord(hstmt, SQL_HANDLE_STMT, rc);

SQL_DATE_STRUCT dateVal;
SQLWCHAR firstNameVal[50];
SQLWCHAR lastNameVal[50];
SQLCHAR SSNVal[12];
SQLLEN cbdate;   // size of date structure  

int rowcount = 0;
while (SQL_SUCCEEDED(SQLFetch(hstmt)))
{
    rowcount++;
    SQLGetData(hstmt, 1, SQL_C_CHAR, &SSNVal, 11, &cbSSN);
    SQLGetData(hstmt, 2, SQL_C_WCHAR, &firstNameVal, 50, &cbFirstName);
    SQLGetData(hstmt, 3, SQL_C_WCHAR, &lastNameVal, 50, &cbLastName);
    SQLGetData(hstmt, 4, SQL_C_TYPE_DATE, &dateVal, 10, &cbdate);        
}

Как избежать распространенных проблем при запросе зашифрованных столбцовAvoiding Common Problems when Querying Encrypted Columns

В этом разделе описываются общие категории ошибок, возникающих при выполнении запросов к зашифрованным столбцам из приложений ODBC, и приводятся рекомендации о том, как их избежать.This section describes common categories of errors when querying encrypted columns from ODBC applications and a few guidelines on how to avoid them.

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

Постоянное шифрование поддерживает несколько преобразований для зашифрованных типов данных.Always Encrypted supports few conversions for encrypted data types. Подробный список поддерживаемых преобразований типов см. в статье Always Encrypted (ядро СУБД).See Always Encrypted (Database Engine) for the detailed list of supported type conversions. Чтобы избежать ошибок преобразования типов данных, старайтесь соблюдать следующие моменты при использовании SQLBindParameter с параметрами, предназначенными для зашифрованных столбцов.To avoid data type conversion errors, make sure that you observe the following points when using SQLBindParameter with parameters targeting encrypted columns:

  • Тип SQL для параметра всегда точно совпадает с типом целевого столбца или может быть преобразован в тип этого столбца.The SQL type of the parameter is either exactly the same as the type of the targeted column, or the conversion from the SQL type to the type of the column is supported.

  • Точность и масштаб параметров, предназначенных для столбцов типов данных SQL Server decimal и numeric, соответствуют точности и масштабу, настроенным для конечного столбца.The precision and scale of parameters targeting columns of the decimal and numeric SQL Server data types is the same as the precision and scale configured for the target column.

  • В запросах, которые изменяют конечный столбец, точность параметров, предназначенных для столбцов типов данных SQL Server datetime2, datetimeoffset или time, не превышает точность для конечного столбца.The precision of parameters targeting columns of datetime2, datetimeoffset, or time SQL Server data types is not greater than the precision for the target column, in queries that modify the target column.

Ошибки, возникающие из-за передачи значений в виде открытого текста, а не в зашифрованном видеErrors due to passing plaintext instead of encrypted values

Любое значение, предназначенное для зашифрованного столбца, должно быть зашифровано до отправки на сервер.Any value that targets an encrypted column needs to be encrypted before being sent to the server. Попытка вставки, изменения или фильтрации по значению в виде открытого текста в зашифрованном столбце приведет к возникновению ошибки.An attempt to insert, modify, or filter by a plaintext value on an encrypted column will result in an error. Чтобы избежать таких ошибок, убедитесь в том, что:To prevent such errors, make sure that:

  • Функция Always Encrypted включена (через имя DSN, в строке подключения, перед подключением через атрибут подключения SQL_COPT_SS_COLUMN_ENCRYPTION для конкретного подключения или через атрибут инструкции SQL_SOPT_SS_COLUMN_ENCRYPTION для конкретной инструкции).Always Encrypted is enabled (in the DSN, the connection string, before connecting by setting the SQL_COPT_SS_COLUMN_ENCRYPTION connection attribute for a specific connection, or the SQL_SOPT_SS_COLUMN_ENCRYPTION statement attribute for a specific statement).

  • для отправки данных, предназначенных для зашифрованных столбцов, используется параметр SQLBindParameter.You use SQLBindParameter to send data targeting encrypted columns. В примере ниже показан запрос, который вместо передачи литерала как аргумента объекта SQLBindParameter неправильно выполняет фильтрацию по литералу или константе в зашифрованном столбце (SSN).The example below shows a query that incorrectly filters by a literal/constant on an encrypted column (SSN), instead of passing the literal as an argument to SQLBindParameter.

string queryText = "SELECT [SSN], [FirstName], [LastName], [BirthDate] FROM [dbo].[Patients] WHERE SSN='795-73-9838'";

Меры предосторожности при использовании SQLSetPos и SQLMoreResultsPrecautions when using SQLSetPos and SQLMoreResults

функция SQLSetPos;SQLSetPos

API SQLSetPos позволяет приложению обновлять строки в результирующем наборе с использованием буферов, которые были привязаны с помощью SQLBindCol и в которые были получены данные строк.The SQLSetPos API allows an application to update rows in a resultset using buffers that were bound with SQLBindCol and into which row data was previously fetched. Из-за асимметричного поведения заполнения для зашифрованных типов фиксированной длины существует риск неожиданно изменить данные в этих столбцах при обновлении других столбцов в той же строке.Due to the asymmetric padding behavior of encrypted fixed-length types, it is possible to unexpectedly alter the data of these columns while performing updates on other columns in the row. При использовании Always Encrypted символьные значения фиксированной длины будут заполняться в тех случаях, когда значение меньше размера буфера.With AE, fixed length character values will be padded if the value is smaller than the buffer size.

Чтобы устранить это поведение, используйте флаг SQL_COLUMN_IGNORE для пропуска тех столбцов, которые не должны обновляться при SQLBulkOperations и при использовании SQLSetPos для обновлений на основе курсора.To mitigate this behavior, use the SQL_COLUMN_IGNORE flag to ignore columns that will not be updated as part of SQLBulkOperations and when using SQLSetPos for cursor based updates. Все столбцы, которые не изменяются приложением напрямую, следует игнорировать по соображениям производительности и для того, чтобы избежать усечения столбцов, привязанных к буферу меньше их фактического размера (в базе данных).All columns that are not being directly modified by the application should be ignored, both for performance and to avoid truncation of columns that are bound to a buffer smaller than their actual (DB) size. Дополнительные сведения см. в справочнике по функции SQLSetPos.For more information, see SQLSetPos Function reference.

SQLMoreResults и SQLDescribeColSQLMoreResults & SQLDescribeCol

Приложения могут вызывать SQLDescribeCol, чтобы возвращать метаданные о столбцах в подготовленных инструкциях.Application programs may call SQLDescribeCol to return metadata about columns in prepared statements. Если включена функция Always Encrypted, вызов SQLMoreResults перед вызовом SQLDescribeCol приводит к вызову sp_describe_first_result_set, в результате чего неверно возвращаются метаданные с указанием открытого текста для зашифрованных столбцов.When Always Encrypted is enabled, calling SQLMoreResults before calling SQLDescribeCol causes sp_describe_first_result_set to be called, which does not correctly return the plaintext metadata for encrypted columns. Чтобы избежать этой проблемы, вызывайте SQLDescribeCol для подготовленных инструкций перед вызовом SQLMoreResults.To avoid this issue, call SQLDescribeCol on prepared statements before calling SQLMoreResults.

Управление влиянием Always Encrypted на производительностьControlling the Performance Impact of Always Encrypted

Так как Always Encrypted является технологией шифрования на стороне клиента, значительное влияние на производительность происходит на стороне клиента, а не в базе данных.Because Always Encrypted is a client-side encryption technology, most of the performance overhead is observed on the client side, not in the database. Помимо затрат на операции шифрования и расшифровки существуют и другие источники снижения производительности на стороне клиента:Apart from the cost of encryption and decryption operations, the other sources of performance overhead on the client side are:

  • Дополнительные обращения к базе данных для получения метаданных для параметров запроса.Additional round trips to the database to retrieve metadata for query parameters.

  • Вызовы хранилища главных ключей столбцов для доступа к главному ключу столбца.Calls to a column master key store to access a column master key.

В этом разделе описываются процессы оптимизации производительности, встроенные в ODBC Driver for SQL Server, и способы управления влиянием двух указанных выше факторов на производительность.This section describes the built-in performance optimizations in the ODBC Driver for SQL Server and how you can control the impact of the above two factors on performance.

Управление обращениями для получения метаданных для параметров запросаControlling Round-trips to Retrieve Metadata for Query Parameters

Если для соединения включена функция Always Encrypted, по умолчанию драйвер будет вызывать sys.sp_describe_parameter_encryption для каждого параметризованного запроса, передавая инструкцию запроса (без значений параметров) в SQL Server.If Always Encrypted is enabled for a connection, the driver will, by default, call sys.sp_describe_parameter_encryption for each parameterized query, passing the query statement (without any parameter values) to SQL Server. Эта хранимая процедура анализирует инструкцию запроса и выясняет, нужно ли шифровать параметры. Если да, то она возвращает по каждому параметру связанные с шифрованием сведения, позволяющие драйверу шифровать их.This stored procedure analyzes the query statement to find out if any parameters need to be encrypted, and if so, returns the encryption-related information for each parameter to allow the driver to encrypt them. Описанное выше поведение гарантирует для клиентского приложения высокий уровень прозрачности. Так как значения, предназначенные для зашифрованных столбцов, передаются драйверу в параметрах, приложению (и разработчику приложения) не нужно знать, какие запросы обращаются к зашифрованным столбцам.The above behavior ensures a high-level of transparency to the client application: The application (and the application developer) does not need to be aware of which queries access encrypted columns, as long as the values targeting encrypted columns are passed to the driver in parameters.

Поведение Always Encrypted для отдельных инструкцийPer-Statement Always Encrypted Behavior

Чтобы управлять тем, как получение метаданных шифрования для параметризованных запросов влияет на производительность, вы можете изменять поведение Always Encrypted для отдельных запросов, если эта функция уже включена для подключения.To control the performance impact of retrieving encryption metadata for parameterized queries, you can alter the Always Encrypted behavior for individual queries if it has been enabled on the connection. Это позволяет гарантировать, что sys.sp_describe_parameter_encryption вызывается только для тех запросов, в которых точно есть параметры для зашифрованных столбцов.This way, you can ensure that sys.sp_describe_parameter_encryption is invoked only for queries that you know have parameters targeting encrypted columns. Обратите внимание, что в этом случае снижается прозрачность шифрования: при шифровании дополнительных столбцов в базе данных может потребоваться изменить код приложения в соответствии с изменениями схемы.Note, however, that by doing so, you reduce transparency of encryption: if you encrypt additional columns in your database, you may need to change the code of your application to align it with the schema changes.

Чтобы изменить поведение Always Encrypted для инструкции, вызовите SQLSetStmtAttr и задайте одно из следующих значений для атрибута инструкции SQL_SOPT_SS_COLUMN_ENCRYPTION:To control the Always Encrypted behavior of a statement, call SQLSetStmtAttr to set the SQL_SOPT_SS_COLUMN_ENCRYPTION statement attribute to one of the following values:

ЗначениеValue ОписаниеDescription
SQL_CE_DISABLED (0)SQL_CE_DISABLED (0) Функция Always Encrypted отключена для инструкцииAlways Encrypted is disabled for the statement
SQL_CE_RESULTSETONLY (1)SQL_CE_RESULTSETONLY (1) Только расшифровка.Decryption Only. Расшифровываются результирующие наборы и возвращаемые значения, а параметры не шифруются.Resultsets and return values are decrypted, and parameters are not encrypted
SQL_CE_ENABLED (3)SQL_CE_ENABLED (3) Функция Always Encrypted включена и используется как для параметров, так и для результатовAlways Encrypted is enabled and used for both parameters and results

Новые дескрипторы инструкций, которые создаются для подключения с включенной функцией Always Encrypted, по умолчанию получают значение SQL_CE_ENABLED.New statement handles created from a connection with Always Encrypted enabled default to SQL_CE_ENABLED. Для тех подключений, где эта функция отключена, дескрипторы инструкций по умолчанию получают значение SQL_CE_DISABLED (и вы не сможете включить для них Always Encrypted).Those created from a connection with it disabled default to SQL_CE_DISABLED (and it is not possible to enable Always Encrypted on them.)

Если большинство запросов клиентского приложения обращаются к зашифрованным столбцам, мы рекомендуем выполнить следующее.If most of the queries of a client application access encrypted columns, the following is recommended:

  • Присвойте ключевому слову ColumnEncryption строки подключения значение Enabled.Set the ColumnEncryption connection string keyword to Enabled.

  • Задайте атрибуту SQL_SOPT_SS_COLUMN_ENCRYPTION значение SQL_CE_DISABLED для инструкций, которые не обращаются к зашифрованным столбцам.Set the SQL_SOPT_SS_COLUMN_ENCRYPTION attribute to SQL_CE_DISABLED on statements which do not access any encrypted columns. Это действие отключает возможность вызова sys.sp_describe_parameter_encryption и любых попыток расшифровать значения в результирующем наборе.This will disable both calling sys.sp_describe_parameter_encryption as well as attempts to decrypt any values in the result set.

  • Задайте атрибуту SQL_SOPT_SS_COLUMN_ENCRYPTION значение SQL_CE_RESULTSETONLY для запросов, которые не имеют параметров, требующих шифрования, но получают данные из зашифрованных столбцов.Set the SQL_SOPT_SS_COLUMN_ENCRYPTION attribute to SQL_CE_RESULTSETONLY on statements which do not have any parameters requiring encryption, but retrieve data from encrypted columns. Это действие отключает вызов sys.sp_describe_parameter_encryption и шифрование параметров.This will disable calling sys.sp_describe_parameter_encryption and parameter encryption. Результаты, содержащие зашифрованные столбцы, будут по-прежнему расшифровываться.Results containing encrypted columns will continue to be decrypted.

Параметры безопасности Always EncryptedAlways Encrypted Security Settings

Принудительное шифрование столбцовForce Column Encryption

Чтобы применить шифрование параметра, задайте значение для поля SQL_CA_SS_FORCE_ENCRYPT (дескриптор параметра реализации), вызвав функцию SQLSetDescField.To enforce the encryption of a parameter, set the SQL_CA_SS_FORCE_ENCRYPT implementation parameter descriptor (IPD) field through a call to the SQLSetDescField function. Если это значение отличается от нуля, драйвер будет возвращать ошибку при отсутствии в ответе метаданных шифрования для соответствующего параметра.A non-zero value causes the driver to return an error when no encryption metadata is returned for the associated parameter.

SQLHDESC ipd;
SQLGetStmtAttr(hStmt, SQL_ATTR_IMP_PARAM_DESC, &ipd, 0, 0);
SQLSetDescField(ipd, paramNum, SQL_CA_SS_FORCE_ENCRYPT, (SQLPOINTER)TRUE, SQL_IS_SMALLINT);   

Если SQL Server сообщает драйверу, что параметр не должен быть зашифрован, запросы, использующие этот параметр, завершатся ошибкой.If SQL Server informs the driver that the parameter does not need to be encrypted, queries using that parameter will fail. Это обеспечивает дополнительную защиту от атак на систему безопасности, включающих предоставление клиенту скомпрометированным сервером SQL Server неверных метаданных шифрования, что может привести к раскрытию данных.This provides additional protection against security attacks which involve a compromised SQL Server providing incorrect encryption metadata to the client, which may lead to data disclosure.

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

Чтобы уменьшить количество вызовов к хранилищу главных ключей столбцов для расшифровки ключей шифрования столбцов (CEK), драйвер кэширует ключи CEK в памяти в открытом тексте.To reduce the number of calls to a column master key store to decrypt column encryption keys, the driver caches the plaintext CEKs in memory. Кэш CEK является глобальным для драйвера, а не связывается с отдельным подключением.The CEK cache is global to the driver and not associated with any one connection. Получив ECEK из метаданных базы данных, драйвер сначала пытается найти в кэше CEK в открытом тексте, который соответствует зашифрованному значению ключа.After receiving the ECEK from database metadata, the driver first tries to find the plaintext CEK corresponding to the encrypted key value in the cache. Драйвер обращается к хранилищу ключей, где хранится главный ключ столбца, только в том случае, если ему не удается найти в кэше значение CEK в открытом тексте.The driver calls the key store containing the CMK only if it cannot find the corresponding plaintext CEK in the cache.

Примечание

Драйвер ODBC Driver for SQL Server вытесняет записи из этого кэша через два часа.In the ODBC Driver for SQL Server, the entries in the cache are evicted after a two hour timeout. Это означает, что для каждого конкретного ключа ECEK драйвер обращается в хранилище ключей только один раз за цикл жизни приложения или один раз каждые два часа в зависимости от того, что меньше.This means that for a given ECEK, the driver contacts the key store only once during the lifetime of the application or every two hours, whichever is less.

Начиная с драйвера ODBC Driver for SQL Server версии 17.1, время ожидания кэша для CEK можно изменить с помощью атрибута подключения SQL_COPT_SS_CEKCACHETTL, который указывает количество секунд хранения CEK в кэше.Starting with the ODBC Driver 17.1 for SQL Server, the CEK cache timeout can be adjusted using the SQL_COPT_SS_CEKCACHETTL connection attribute, which specifies the number of seconds a CEK will remain in the cache. В силу глобальной природы кэша этот атрибут можно изменять из любого дескриптора подключения, который допустим для драйвера.Due to the global nature of the cache, this attribute can be adjusted from any connection handle valid for the driver. При уменьшении значения срока жизни ключей из хранилища вытесняются все значения CEK, срок хранения которых не соответствует новому условию.When the cache TTL is decreased, existing CEKs which would exceed the new TTL are also evicted. Если здесь задано значение 0, ключи CEK не кэшируются.If it is 0, no CEKs are cached.

Доверенные пути ключейTrusted Key Paths

Начиная с драйвера ODBC Driver for SQL Server версии 17.1, применяется атрибут подключения SQL_COPT_SS_TRUSTEDCMKPATHS, который позволяет приложению разрешить для операций Always Encrypted только конкретный список ключей CMK, который определяется по путям ключей.Starting with the ODBC Driver 17.1 for SQL Server, the SQL_COPT_SS_TRUSTEDCMKPATHS connection attribute allows an application to require that Always Encrypted operations only use a specified list of CMKs, identified by their key paths. По умолчанию этот атрибут имеет значение NULL, и при этом драйвер принимает любой путь ключа.By default, this attribute is NULL, which means that the driver accepts any key path. Чтобы использовать эту возможность, присвойте SQL_COPT_SS_TRUSTEDCMKPATHS нуль-терминированное строковое значение с расширенными символами, в котором перечислены разделенные нулевым значением допустимые пути ключей.To use this feature, set SQL_COPT_SS_TRUSTEDCMKPATHS to point to a null-delimited, null-terminated wide-character string which lists the allowed key path(s). Участки памяти, на которые ссылается этот атрибут, должны оставаться допустимыми на всем протяжении операций шифрования и расшифровки для того дескриптора подключения, в котором он задан. Драйвер будет постоянно проверять путь CMK, указанный в метаданных сервера, на наличие соответствующего значения в этом списке (без учета регистра).The memory pointed to by this attribute must remain valid during encryption or decryption operations using the connection handle on which it is set --- upon which the driver will check if the CMK path as specified by the server metadata is case-insensitively in this list. Если путь CMK отсутствует в этом списке, операция завершается ошибкой.If the CMK path is not in the list, the operation fails. Чтобы изменить список доверенных ключей CMK, приложение может изменять содержимое памяти, на которую указывает этот атрибут, не изменяя значение самого атрибута.The application can change the contents of memory this attribute points at, to change its list of trusted CMKs, without setting the attribute again.

Работа с хранилищами главных ключей столбцовWorking with Column Master Key Stores

Для шифрования или расшифровки данных драйвер должен получить ключ CEK, который настроен для целевого столбца.To encrypt or decrypt data, the driver needs to obtain a CEK that is configured for the target column. Ключи CEK хранятся в зашифрованном виде (ECEK) в метаданных базы данных.CEKs are stored in encrypted form (ECEKs) in the database metadata. Каждому ключу CEK соответствует определенный ключ CMK, который использовался для его шифрования.Each CEK has a corresponding CMK that was used to encrypt it. Метаданные базы данных не хранят значения CMK, а только имя хранилища ключей и информацию, позволяющую найти нужные CMK в этом хранилище ключей.The database metadata does not store the CMK itself; it only contains the name of the keystore and information which the keystore can use to locate the CMK.

Чтобы получить значение ECEK в открытом тексте, драйвер сначала получает метаданные о ключах CEK и CMK, а затем на основе этих сведений обращается в хранилище ключей, где содержится CMK, и запрашивает расшифрованную версию ECEK.To obtain the plaintext value of an ECEK, the driver first obtains the metadata about both the CEK and its corresponding CMK, and then it uses this information to contact the keystore containing the CMK and requests it to decrypt the ECEK. Драйвер взаимодействует с хранилищем ключей через поставщик хранилища ключей.The driver communicates with a keystore using a keystore provider.

Встроенные поставщики хранилища ключейBuilt-in Keystore Providers

Драйвер ODBC Driver for SQL Server поставляется со следующими встроенными поставщиками хранилища ключей.The ODBC Driver for SQL Server comes with the following built-in keystore providers:

ИмяName ОписаниеDescription Имя (метаданные) поставщикаProvider (metadata) name ДоступностьAvailability
Хранилище ключей AzureAzure Key Vault Хранит CMK в Azure Key VaultStores CMKs in an Azure Key Vault AZURE_KEY_VAULT Windows, macOS, LinuxWindows, macOS, Linux
Хранилище сертификатов WindowsWindows Certificate Store Хранит CMK локально в хранилище ключей WindowsStores CMKs locally in the Windows keystore MSSQL_CERTIFICATE_STORE WindowsWindows
  • Вы (или ваш администратор баз данных) должны проверить правильность имени поставщика, настроенного в метаданных главного ключа столбца, и убедиться в том, что путь к ключу главного ключа столбца соответствует формату пути к ключу для данного поставщика.You (or your DBA) need to make sure that the provider name, configured in the column master key metadata, is correct and the column master key path complies with the key path format for the given provider. Для настройки ключей рекомендуется использовать средство, такое как среда SQL Server Management Studio, которое при выполнении инструкции CREATE COLUMN MASTER KEY (Transact-SQL) автоматически создает допустимые имена поставщиков и пути к ключам.It is recommended that you configure the keys using tools such as SQL Server Management Studio, which automatically generates the valid provider names and key paths when issuing the CREATE COLUMN MASTER KEY (Transact-SQL) statement.

  • Необходимо убедиться в том, что приложение может получать доступ к ключам в хранилище ключей.You need to ensure your application can access the key in the keystore. Для этого может потребоваться предоставить приложению доступ к ключу или хранилищу ключей (в зависимости от хранилища ключей) либо выполнить другие действия по настройке конкретного хранилища ключей.This may involve granting your application access to the key and/or the keystore, depending on the keystore, or performing other keystore-specific configuration steps. Например, для доступа к Azure Key Vault нужно предоставить правильные учетные данные для хранилища ключей.For example, to access an Azure Key Vault, you need to provide the correct credentials to the keystore.

Использование поставщика Azure Key VaultUsing the Azure Key Vault Provider

Хранилище ключей Azure удобно использовать, чтобы хранить главные ключи столбцов для постоянного шифрования, особенно если приложения размещены в Azure.Azure Key Vault (AKV) is a convenient option to store and manage column master keys for Always Encrypted (especially if your applications are hosted in Azure). Драйвер ODBC Driver for SQL Server в Linux, macOS и Windows содержит встроенный поставщик хранилища ключей Azure Key Vault для хранения главного ключа.The ODBC Driver for SQL Server on Linux, macOS, and Windows includes a built-in column master key store provider for Azure Key Vault. Дополнительные сведения о настройке Azure Key Vault для Always Encrypted вы найдете в этом пошаговом руководстве и в статьях Что такое Azure Key Vault? и Создание и хранение главных ключей столбцов (постоянное шифрование).See Azure Key Vault - Step by Step, Getting Started with Key Vault, and Creating Column Master Keys in Azure Key Vault for more information on configuring an Azure Key Vault for Always Encrypted.

Примечание

Драйвер ODBC не поддерживает службы федерации Active Directory (AD FS) для проверки подлинности AKV.The ODBC Driver does not support Active Directory Federation Services for AKV authentication. Если для AKV используется проверка подлинности Azure Active Directory и конфигурация Active Directory включает федеративные службы, проверка подлинности может завершиться ошибкой.If you are using Azure Active Directory authentication to AKV and your Active Directory configuration includes Federated Services, authentication may fail. В Linux и macOS, если используется драйвер версии 17.2 или более поздней, для использования этого поставщика требуется библиотека libcurl, но она не считается явной зависимостью, так как не нужна для других операций с драйвером.On Linux and macOS, for driver version 17.2 and later, libcurl is required to use this provider, but is not an explicit dependency since other operations with the driver do not require it. Если возникает связанная с пакетом libcurl ошибка, убедитесь в том, что он установлен.If you encounter an error regarding libcurl, ensure it is installed.

Драйвер поддерживает проверку подлинности в Azure Key Vault со следующими типами учетных данных.The driver supports authenticating to Azure Key Vault using the following credential types:

  • Имя пользователя и пароль — этот метод использует в качестве учетных данных имя пользователя Azure Active Directory и его пароль.Username/Password - with this method, the credentials are the name of an Azure Active Directory user and its password.

  • Идентификатор и секрет клиента — этот метод использует в качестве учетных данных идентификатор клиента приложения и секрет приложения.Client ID/Secret - with this method, the credentials are an application client ID and an application secret.

Чтобы разрешить драйверу использовать для шифрования столбцов ключи CMK, хранящиеся в Azure Key Vault, укажите в строке подключения следующие ключевые слова:To allow the driver to use CMKs stored in AKV for column encryption, use the following connection-string-only keywords:

Тип учетных данныхCredential Type KeyStoreAuthentication KeyStorePrincipalId KeyStoreSecret
Имя пользователя и парольUsername/password KeyVaultPassword Имя участника-пользователяUser Principal Name ПарольPassword
Идентификатор и секрет клиентаClient ID/secret KeyVaultClientSecret Идентификатор клиентаClient ID СекретSecret

Примеры строк подключенияExample Connection Strings

Следующие строки подключения демонстрируют проверку подлинности в Azure Key Vault с двумя разными типами учетных данных.The following connection strings show how to authenticate to Azure Key Vault with the two credential types:

Идентификатор и секрет клиента:ClientID/Secret:

DRIVER=ODBC Driver 13 for SQL Server;SERVER=myServer;Trusted_Connection=Yes;DATABASE=myDB;ColumnEncryption=Enabled;KeyStoreAuthentication=KeyVaultClientSecret;KeyStorePrincipalId=<clientId>;KeyStoreSecret=<secret>

Имя пользователя и пароль:Username/Password:

DRIVER=ODBC Driver 13 for SQL Server;SERVER=myServer;Trusted_Connection=Yes;DATABASE=myDB;ColumnEncryption=Enabled;KeyStoreAuthentication=KeyVaultPassword;KeyStorePrincipalId=<username>;KeyStoreSecret=<password>

Чтобы использовать Azure Key Vault в качестве хранилища для CMK не нужно вносить других изменений в приложение ODBC.No other ODBC application changes are required to use AKV for CMK storage.

Использование поставщика хранилища сертификатов WindowsUsing the Windows Certificate Store Provider

Драйвер ODBC Driver for SQL Server в Windows содержит встроенный поставщик MSSQL_CERTIFICATE_STORE хранилища сертификатов Windows для хранения главного ключа.The ODBC Driver for SQL Server on Windows includes a built-in column master key store provider for the Windows Certificate Store, named MSSQL_CERTIFICATE_STORE. (Этот поставщик недоступен для macOS и Linux.) При использовании этого поставщика ключи CMK хранятся локально на клиентском компьютере, и для работы с ним не нужно вносить никаких дополнительных изменений в конфигурацию приложения.(This provider is not available on macOS or Linux.) With this provider, the CMK is stored locally on the client machine and no additional configuration by the application is necessary to use it with the driver. Но такому приложению необходимы права доступа к сертификату и закрытому ключу, размещенным в хранилище.However, the application must have access to the certificate and its private key in the store. Дополнительные сведения см. в статье Создание и хранение главных ключей столбцов (постоянное шифрование).See Create and Store Column Master Keys (Always Encrypted) for more information.

Использование настраиваемых поставщиков хранилища ключейUsing Custom Keystore Providers

Драйвер ODBC Driver for SQL Server также поддерживает пользовательские сторонние поставщики хранилища ключей через интерфейс CEKeystoreProvider.The ODBC Driver for SQL Server also supports custom third-party keystore providers using the CEKeystoreProvider interface. Он позволяет приложению загружать, запрашивать и настраивать поставщики хранилища ключей, чтобы драйвер мог использовать их для доступа к зашифрованным столбцам.This allows an application to load, query, and configure keystore providers so that they can be used by the driver to access encrypted columns. Приложения могут напрямую взаимодействовать с поставщиком хранилища ключей, чтобы шифровать ключи CEK для хранения в SQL Server и выполнять другие задачи ODBC помимо доступа к зашифрованным столбцам. Дополнительные сведения см. в статье о пользовательских поставщиках хранилища ключей.Applications may also directly interact with a keystore provider in order to encrypt CEKs for storage in SQL Server and perform tasks beyond accessing encrypted columns with ODBC; for more information, see Custom Keystore Providers.

Для взаимодействия с пользовательскими поставщиками хранилища ключей используются два атрибута подключения.Two connection attributes are used to interact with custom keystore providers. Подробные сведения.They are:

  • SQL_COPT_SS_CEKEYSTOREPROVIDER

  • SQL_COPT_SS_CEKEYSTOREDATA

Первый из них позволяет загружать и перечислять загруженные поставщики хранилища ключей, а второй нужен для взаимодействия между поставщиком и приложением.The former is used to load and enumerate loaded keystore providers, while the latter enables application-provider communications. Эти атрибуты подключения можно применять в любое время, как до так и после установки подключения, так как взаимодействие между поставщиком и приложением не требует обмена данными с SQL Server.These connection attributes may be used at any time, before or after establishing a connection, since application-provider interaction does not involve communication with SQL Server. Но перед подключением, когда драйвер еще не загружен, установка и получение этих атрибутов будет обрабатываться диспетчером драйверов и может приводить к неожиданным результатам.However, because the driver has not been loaded yet, setting and getting these attributes before connecting will cause them to be processed by the Driver Manager, and may not yield the expected results.

Загрузка поставщика хранилища ключейLoading a Keystore Provider

Настройка атрибута подключения SQL_COPT_SS_CEKEYSTOREPROVIDER позволяет клиентскому приложению загрузить библиотеку поставщика, что делает доступными для использования содержащихся в этой библиотеке поставщиков хранилища ключей.Setting the SQL_COPT_SS_CEKEYSTOREPROVIDER connection attribute enables a client application to load a provider library, making available for use the keystore providers contained therein.

SQLRETURN SQLSetConnectAttr( SQLHDBC ConnectionHandle, SQLINTEGER Attribute, SQLPOINTER ValuePtr, SQLINTEGER StringLength);
АргументArgument ОписаниеDescription
ConnectionHandle [Input] Дескриптор подключения[Input] Connection handle. Это должен быть допустимый дескриптор подключения, но загруженные через любой дескриптор подключения поставщики становятся доступны из любого дескриптора в том же процессе.Must be a valid connection handle, but providers loaded via one connection handle are accessible from any other in the same process.
Attribute [Input] Атрибут для задания константы SQL_COPT_SS_CEKEYSTOREPROVIDER.[Input] Attribute to set: the SQL_COPT_SS_CEKEYSTOREPROVIDER constant.
ValuePtr [Input] Указатель на нуль-терминированную строку, которая определяет имя файла библиотеки поставщика.[Input] Pointer to a null-terminated character string specifying the filename of the provider library. Для SQLSetConnectAttrA это строка ANSI (multibyte).For SQLSetConnectAttrA, this is an ANSI (multibyte) string. Для SQLSetConnectAttrW это строка Юникода (wchar_t).For SQLSetConnectAttrW, this is a Unicode (wchar_t) string.
StringLength [Input] Длина строки ValuePtr или SQL_NTS.[Input] The length of the ValuePtr string, or SQL_NTS.

Драйвер пытается загрузить библиотеку, указанную параметром ValuePtr, через определяемый платформой механизм загрузки динамических библиотек (dlopen() в Linux и macOS, LoadLibrary() в Windows) и добавляет все определенные в ней поставщики в список известных поставщиков для драйвера.The driver attempts to load the library identified by the ValuePtr parameter using the platform-defined dynamic library loading mechanism (dlopen() on Linux and macOS, LoadLibrary() on Windows), and adds any providers defined therein to the list of providers known to the driver. Могут возникать следующие ошибки.The following errors may occur:

ОшибкаError ОписаниеDescription
CE203 Не удалось загрузить динамическую библиотеку.The dynamic library could not be loaded.
CE203 В библиотеке не удалось найти экспортированный символ CEKeyStoreProvider.The "CEKeyStoreProvider" exported symbol was not found in the library.
CE203 Один или несколько поставщиков из этой библиотеки уже загружены.One or more providers in the library are already loaded.

SQLSetConnectAttr возвращает обычные значения ошибки или успешного завершения, а по любым возникающим ошибкам можно получить дополнительные сведения через стандартный механизм диагностики ODBC.SQLSetConnectAttr returns the usual error or success values, and additional information is available for any errors which occurred via the standard ODBC diagnostic mechanism.

Примечание

Создателю приложения следует следить за тем, чтобы все пользовательские поставщики загружались до отправки использующих их запросов через любое подключение.The application programmer must ensure that any custom providers are loaded before any query requiring them is sent over any connection. Несоблюдение этого правила приведет к ошибке.Failure to do so results in the error:

ОшибкаError ОписаниеDescription
CE200 Поставщик хранилища ключей %1 не найден.Keystore provider %1 not found. Убедитесь, что загружена соответствующая библиотека поставщика хранилища ключей.Ensure that the appropriate keystore provider library has been loaded.

Примечание

Средства реализации поставщика хранилища ключей не должны использовать строку MSSQL в именах пользовательских поставщиков.Keystore provider implementors should avoid the use of MSSQL in the name of their custom providers. Этот термин зарезервирован исключительно для корпорации Майкрософт, и его применение может привести к конфликту с будущими встроенными поставщиками.This term is reserved exclusively for Microsoft use and may cause conflicts with future built-in providers. Наличие этого термина в имени пользовательского поставщика может создавать предупреждение ODBC.Using this term in the name of a custom provider may result in an ODBC warning.

Получение списка загруженных поставщиковGetting the List of Loaded Providers

Получение этого атрибута подключения позволяет клиентскому приложению определить, какие поставщики хранилища ключей в настоящее время загружены в драйвер (включая встроенные). Это можно сделать только после подключения.Getting this connection attribute enables a client application to determine the keystore providers currently loaded in the driver (including those built in.) This can only be performed after connecting.

SQLRETURN SQLGetConnectAttr( SQLHDBC ConnectionHandle, SQLINTEGER Attribute, SQLPOINTER ValuePtr, SQLINTEGER BufferLength, SQLINTEGER * StringLengthPtr);
АргументArgument ОписаниеDescription
ConnectionHandle [Input] Дескриптор подключения[Input] Connection handle. Это должен быть допустимый дескриптор подключения, но загруженные через любой дескриптор подключения поставщики становятся доступны из любого дескриптора в том же процессе.Must be a valid connection handle, but providers loaded via one connection handle are accessible from any other in the same process.
Attribute [Input] Атрибут для получения константы SQL_COPT_SS_CEKEYSTOREPROVIDER.[Input] Attribute to retrieve: the SQL_COPT_SS_CEKEYSTOREPROVIDER constant.
ValuePtr [Output] Указатель на участок памяти, в котором будет возвращено имя следующего загруженного поставщика.[Output] A pointer to memory in which to return the next loaded provider name.
BufferLength [Input] Длина буфера ValuePtr.[Input] The length of the buffer ValuePtr.
StringLengthPtr [Output] Указатель на буфер, в котором будет возвращено общее число байтов (за исключением нулевого символа завершения строки), доступных для получения из *ValuePtr.[Output] A pointer to a buffer in which to return the total number of bytes (excluding the null-termination character) available to return in *ValuePtr. Если ValuePtr является пустым указателем, длина не возвращается.If ValuePtr is a null pointer, no length is returned. Если значением атрибута является строка символов, в которой количество доступных байтов превышает разность между значением BufferLength и длиной нуль-терминированной строки, драйвер усекает данные в *ValuePtr до значения этой разности и завершает полученную строку нулевым символом.If the attribute value is a character string and the number of bytes available to return is greater than BufferLength minus the length of the null-termination character, the data in *ValuePtr is truncated to BufferLength minus the length of the null-termination character and is null-terminated by the driver.

Каждая операция Get возвращает имя текущего поставщика и увеличивает значение внутреннего счетчика до следующего поставщика, чтобы обеспечить возможность получить весь список.To allow retrieving the entire list, every Get operation returns the current provider's name, and increments an internal counter to the next one. Когда этот счетчик достигнет конца списка, возвращается пустая строка ("") и счетчик сбрасывается. Следующая операция Get снова начинает процесс с начала списка.Once this counter reaches the end of the list, an empty string ("") is returned, and the counter is reset; successive Get operations then proceed again from the beginning of the list.

Взаимодействие с поставщиками хранилища ключейCommunicating with Keystore Providers

Атрибут подключения SQL_COPT_SS_CEKEYSTOREDATA позволяет клиентскому приложению взаимодействовать с загруженными поставщиками хранилища ключей, например для настройки дополнительных параметров или передачи материала ключей. Взаимодействие между клиентским приложением и поставщиком выполняется по простому протоколу формата "запрос и ответ" через запросы Get и Set с помощью этого атрибута соединения.The SQL_COPT_SS_CEKEYSTOREDATA connection attribute enables a client application to communicate with loaded keystore providers for configuring additional parameters, keying material, etc. The communication between a client application and a provider follows a simple request-response protocol, based on Get and Set requests using this connection attribute. Взаимодействие всегда инициируется клиентским приложением.Communication is initiated only by the client application.

Примечание

В силу природы вызовов ODBC и реакции CEKeyStoreProvider на них (SQLGet/SetConnectAttr) интерфейс ODBC поддерживает задание данных с точностью до контекста подключения.Due to the nature of the ODBC calls CEKeyStoreProvider's respond to (SQLGet/SetConnectAttr), the ODBC interface only supports setting data at the resolution of the connection context.

Приложение взаимодействует с поставщиками хранилища ключей через драйвер с использованием структуры CEKeystoreData:The application communicates with keystore providers through the driver via the CEKeystoreData structure:

typedef struct CEKeystoreData {
wchar_t *name;
unsigned int dataSize;
char data[];
} CEKEYSTOREDATA;
АргументArgument ОписаниеDescription
name [Input] В запросе Set содержит имя поставщика, которому отправляются данные.[Input] Upon Set, the name of the provider to which the data is sent. Не учитывается в запросе Get.Ignored upon Get. Нуль-терминированная строка расширенных символов.Null-terminated, wide-character string.
dataSize [Input] Размер массива данных в соответствии со структурой.[Input] The size of the data array following the structure.
data [InOut] В запросе Set содержит данные для отправки поставщику.[InOut] Upon Set, the data to be sent to the provider. Здесь могут быть произвольные данные, драйвер не пытается их обрабатывать.This may be arbitrary data; the driver makes no attempt to interpret it. В запросе Get указывает на буфер, в который будут помещаться полученные из поставщика данные.Upon Get, the buffer to receive the data read from the provider.

Запись данных в поставщикWriting data to a provider

Вызов SQLSetConnectAttr с атрибутом SQL_COPT_SS_CEKEYSTOREDATA записывает "пакет" данных в указанный поставщик хранилища ключей.A SQLSetConnectAttr call using the SQL_COPT_SS_CEKEYSTOREDATA attribute writes a "packet" of data to the specified keystore provider.

SQLRETURN SQLSetConnectAttr( SQLHDBC ConnectionHandle, SQLINTEGER Attribute, SQLPOINTER ValuePtr, SQLINTEGER StringLength);
АргументArgument ОписаниеDescription
ConnectionHandle [Input] Дескриптор подключения[Input] Connection handle. Это должен быть допустимый дескриптор подключения, но загруженные через любой дескриптор подключения поставщики становятся доступны из любого дескриптора в том же процессе.Must be a valid connection handle, but providers loaded via one connection handle are accessible from any other in the same process.
Attribute [Input] Атрибут для задания константы SQL_COPT_SS_CEKEYSTOREDATA.[Input] Attribute to set: the SQL_COPT_SS_CEKEYSTOREDATA constant.
ValuePtr [Input] Указатель на структуру CEKeystoreData.[Input] Pointer to a CEKeystoreData structure. Поле имени структуры идентифицирует поставщик, для которого предназначены данные.The name field of the structure identifies the provider for which the data is intended.
StringLength [Input] Константа SQL_IS_POINTER[Input] SQL_IS_POINTER constant

Подробные сведения об ошибке можно получить с помощью SQLGetDiacRec.Additional detailed error information may be obtained via SQLGetDiacRec.

Примечание

Поставщик может использовать дескриптор подключения для связи записываемых данных с конкретным подключением, если потребуется.The provider can use the connection handle to associate the written data to a specific connection, if it so desires. Это полезно для реализации раздельных конфигураций для подключений.This is useful for implementing per-connection configuration. Также он может игнорировать контекст подключения и всегда использовать данные одинаково, независимо от подключения, через которые они отправлены.It may also ignore the connection context and treat the data identically regardless of the connection used to send the data. Дополнительные сведения см. в разделе о контексте связи.See Context Association for more information.

Считывание данных из поставщикаReading data from a provider

Вызов SQLGetConnectAttr с атрибутом SQL_COPT_SS_CEKEYSTOREDATA считывает "пакет" данных из поставщика, в который осуществлялась последняя операция записи.A call to SQLGetConnectAttr using the SQL_COPT_SS_CEKEYSTOREDATA attribute reads a "packet" of data from the last-written-to provider. Если операций записи еще не было, возникает ошибка последовательности функций.If there was none, a Function Sequence Error occurs. При реализации поставщиков хранилища ключей мы рекомендуем реализовать поддержку "фиктивных записей" длиной 0 байт, которые позволят выбирать поставщик для операций чтения без побочных эффектов, если такой сценарий имеет смысл.Keystore provider implementers are encouraged to support "dummy writes" of 0 bytes as a way of selecting the provider for read operations without causing other side-effects, if it makes sense to do so.

SQLRETURN SQLGetConnectAttr( SQLHDBC ConnectionHandle, SQLINTEGER Attribute, SQLPOINTER ValuePtr, SQLINTEGER BufferLength, SQLINTEGER * StringLengthPtr);
АргументArgument ОписаниеDescription
ConnectionHandle [Input] Дескриптор подключения[Input] Connection handle. Это должен быть допустимый дескриптор подключения, но загруженные через любой дескриптор подключения поставщики становятся доступны из любого дескриптора в том же процессе.Must be a valid connection handle, but providers loaded via one connection handle are accessible from any other in the same process.
Attribute [Input] Атрибут для получения константы SQL_COPT_SS_CEKEYSTOREDATA.[Input] Attribute to retrieve: the SQL_COPT_SS_CEKEYSTOREDATA constant.
ValuePtr [Output] Указатель на структуру CEKeystoreData, в которой размещаются считанные из поставщика данные.[Output] A pointer to a CEKeystoreData structure in which the data read from the provider is placed.
BufferLength [Input] Константа SQL_IS_POINTER[Input] SQL_IS_POINTER constant
StringLengthPtr [Output] Указатель на буфер, в котором возвращается значение BufferLength.[Output] A pointer to a buffer in which to return BufferLength. Если *ValuePtr является пустым указателем, длина не возвращается.If *ValuePtr is a null pointer, no length is returned.

Вызывающий объект должен выделить буфер достаточной длины для структуры CEKEYSTOREDATA, чтобы записать данные из поставщика.The caller must ensure that a buffer of sufficient length following the CEKEYSTOREDATA structure is allocated for the provider to write into. При завершении операции поле dataSize заполняется фактической длиной данных, считанных из поставщика.Upon return, its dataSize field is updated with the actual length of data read from the provider. Подробные сведения об ошибке можно получить с помощью SQLGetDiacRec.Additional detailed error information may be obtained via SQLGetDiacRec.

Этот интерфейс не накладывает дополнительных требований на формат передачи данных между приложением и поставщиком хранилища ключей.This interface places no additional requirements on the format of data transferred between an application and a keystore provider. Каждый поставщик может определить свой формат данных и протоколов в зависимости от конкретных потребностей.Each provider can define its own protocol/data format, depending on its needs.

Пример реализации поставщика хранилища ключей можно изучить в статье Custom Keystore Providers (Пользовательские поставщики хранилища ключей).For an example of implementing your own keystore provider, see Custom Keystore Providers

Ограничения драйвера ODBC при использовании Always EncryptedLimitations of the ODBC driver when using Always Encrypted

Асинхронные операцииAsynchronous Operations

Драйвер ODBC разрешает использование асинхронных операций совместно с Always Encrypted, но такой режим использования негативно влияет на производительность операций.While the ODBC driver will allow the use of asynchronous operations with Always Encrypted, there is a performance impact on the operations when Always Encrypted is enabled. Вызов sys.sp_describe_parameter_encryption для определения метаданных шифрования для инструкции является блокирующим, то есть драйвер будет ждать получения метаданных от сервера, прежде чем возвращать SQL_STILL_EXECUTING.The call to sys.sp_describe_parameter_encryption to determine encryption metadata for the statement is blocking and will cause the driver to wait for the server to return the metadata before returning SQL_STILL_EXECUTING.

Получение данных частями с помощью SQLGetDataRetrieve data in parts with SQLGetData

В драйвере ODBC Driver for SQL Server версий старше 17 не было возможности получать по частям зашифрованные столбцы с символьными или двоичными данными через SQLGetData.Before ODBC Driver 17 for SQL Server, encrypted character and binary columns cannot be retrieved in parts with SQLGetData. Допускался только один вызов SQLGetData, для которого требовался буфер достаточной длины для размещения полных данных из столбца.Only one call to SQLGetData can be made, with a buffer of sufficient length to contain the entire column's data.

Отправка данных частями с помощью SQLGetDataSend data in parts with SQLPutData

В драйвере ODBC Driver for SQL Server версий старше 17.3 не было возможности отправлять частями данные для вставки или сравнения через SQLPutData.Before ODBC Driver 17.3 for SQL Server, data for insertion or comparison cannot be sent in parts with SQLPutData. Допускался только один вызов SQLPutData с буфером, который содержит полные данные.Only one call to SQLPutData can be made, with a buffer containing the entire data. Для вставки в зашифрованные столбцы длинных данных используйте интерфейс API массового копирования, который описан в следующем разделе, передавая ему файл входных данных.For inserting long data into encrypted columns, use the Bulk Copy API, described in the next section, with an input data file.

Зашифрованные данные money и smallmoneyEncrypted money and smallmoney

Шифрование столбцов типа money или smallmoney нельзя указать с помощью параметров, так как с этими типами не сопоставляется ни один тип данных ODBC. Подобная попытка приведет к ошибке конфликта типов операндов.Encrypted money or smallmoney columns cannot be targeted by parameters, since there is no specific ODBC data type which maps to those types, resulting in Operand Type Clash errors.

Массовое копирование зашифрованных столбцовBulk Copy of Encrypted Columns

Начиная с драйвера Microsoft ODBC Driver for SQL Server версии 17 для данных Always Encrypted поддерживаются функции массового копирования SQL и служебная программа bcp.Use of the SQL Bulk Copy functions and the bcp utility is supported with Always Encrypted since ODBC Driver 17 for SQL Server. API-интерфейсы массового копирования (bcp_*) и служебная программа bcp поддерживают вставку и извлечение данных в форматах открытого текста (с шифрованием при вставке и расшифровкой при извлечении) и зашифрованного текста (без дополнительной обработки).Both plaintext (encrypted on insertion and decrypted on retrieval) and ciphertext (transferred verbatim) can be inserted and retrieved using the Bulk Copy (bcp_*) APIs and the bcp utility.

  • Чтобы получить зашифрованный текст в формате varbinary(max) (например, для массовой загрузки в другую базу данных), создайте подключение без параметра ColumnEncryption (или присвойте ему значение Disabled) и выполните операцию BCP OUT.To retrieve ciphertext in varbinary(max) form (e.g. for bulk loading into a different database), connect without the ColumnEncryption option (or set it to Disabled) and perform a BCP OUT operation.

  • Чтобы вставка и извлечение выполнялись в открытом тексте, который драйвер будет прозрачно шифровать и расшифровывать, достаточно задать параметру ColumnEncryption значение Enabled.To insert and retrieve plaintext, and let the driver transparently perform encryption and decryption as required, setting ColumnEncryption to Enabled is sufficient. Все остальные функции API BCP сохраняются неизменными.The functionality of the BCP API is otherwise unchanged.

  • Чтобы вставка и извлечение выполнялись в формате varbinary(max) (как в примере выше), присвойте параметру BCPMODIFYENCRYPTED значение TRUE и выполните операцию BCP IN.To insert ciphertext in varbinary(max) form (e.g. as retrieved above), set the BCPMODIFYENCRYPTED option to TRUE and perform a BCP IN operation. Чтобы результирующие данные можно было расшифровать, ключ CEK для целевого столбца должен совпадать с тем ключом, который изначально применялся для получения зашифрованного текста.In order for the resulting data to be decryptable, ensure that the destination column's CEK is the same as that from which the ciphertext was originally obtained.

Если вы используете служебную программу bcp, для указания параметра ColumnEncryption следует указать аргумент -D и имя источника данных, содержащего нужное значение.When using the bcp utility: To control the ColumnEncryption setting, use the -D option and specify a DSN containing the desired value. Чтобы вставить зашифрованные данные, включите для пользователя параметр ALLOW_ENCRYPTED_VALUE_MODIFICATIONS.To insert ciphertext, ensure the ALLOW_ENCRYPTED_VALUE_MODIFICATIONS setting of the user is enabled.

Следующая таблица содержит краткое описание действий, доступных при работе с зашифрованным столбцом.The following table provides a summary of the actions when operating on an encrypted column:

ColumnEncryption Направление массового копированияBCP Direction ОписаниеDescription
Disabled Исходящее (к клиенту)OUT (to client) Получение зашифрованного текста.Retrieves ciphertext. Данные предоставляются в формате varbinary(max) .The observed datatype is varbinary(max).
Enabled Исходящее (к клиенту)OUT (to client) Получение открытого текста.Retrieves plaintext. Драйвер расшифрует данные столбца.The driver will decrypt the column data.
Disabled Входящее (к серверу)IN (to server) Вставка зашифрованного текстаInserts ciphertext. Предназначено для непрозрачного перемещения зашифрованных данных, которые не нужно расшифровывать.This is intended for opaquely moving encrypted data without requiring it to be decrypted. Операция завершится ошибкой, если для пользователя не установлен параметр ALLOW_ENCRYPTED_VALUE_MODIFICATIONS или для дескриптора соединения не указан атрибут BCPMODIFYENCRYPTED.The operation will fail if the ALLOW_ENCRYPTED_VALUE_MODIFICATIONS option is not set on the user, or BCPMODIFYENCRYPTED is not set on the connection handle. Дополнительную информацию см. ниже.See below for more information.
Enabled Входящее (к серверу)IN (to server) Вставка обычного текста.Inserts plaintext. Драйвер зашифрует данные столбца.The driver will encrypt the column data.

Параметр BCPMODIFYENCRYPTEDThe BCPMODIFYENCRYPTED option

Чтобы предотвратить повреждение данных, сервер обычно не допускает прямую вставку зашифрованных данных в зашифрованный столбец, то есть такая попытка завершится ошибкой. Но для массовой загрузки зашифрованных данных с помощью API BCP вы можете установить для параметра BCPMODIFYENCRYPTED bcp_control значение TRUE, которое разрешает прямую вставку зашифрованного текста и снижает риск повреждения зашифрованных данных по сравнению с применением параметра ALLOW_ENCRYPTED_VALUE_MODIFICATIONS для учетной записи пользователя.To prevent data corruption, the server normally does not allow inserting ciphertext directly into an encrypted column, and thus attempts to do so will fail; however, for bulk loading of encrypted data using the BCP API, setting the BCPMODIFYENCRYPTED bcp_control option to TRUE will allow ciphertext to be inserted directly, and reduces the risk of corrupting encrypted data over setting the ALLOW_ENCRYPTED_VALUE_MODIFICATIONS option on the user account. Но при этом ключи должны всегда соответствовать данным. Мы рекомендуем выполнить несколько проверок чтением после массовой вставки данных и перед их дальнейшим использованием.Nonetheless, the keys must match the data and it is a good idea to perform some read-only checks of the inserted data after the bulk insertion and before further use.

Дополнительные сведения см. в разделе Перенос конфиденциальных данных с помощью функции постоянного шифрования.See Migrate Sensitive Data Protected by Always Encrypted for more information.

Сводные данные по API Always EncryptedAlways Encrypted API Summary

Ключевые слова в строке подключенияConnection String Keywords

ИмяName ОписаниеDescription
ColumnEncryption Допустимые значения: Enabled/Disabled.Accepted values are Enabled/Disabled.
Enabled — включает функцию Always Encrypted для подключения.Enabled -- enables Always Encrypted functionality for the connection.
Disabled — отключает для подключения функцию Always Encrypted.Disabled -- disable Always Encrypted functionality for the connection.
тип данных (версия 17,4 и более поздние) включает Always encrypted с безопасным типомпротокола анклава и аттестации и связанными данными аттестации.type,data -- (version 17.4 and later) enables Always Encrypted with secure enclave and attestation protocol type, and associated attestation data data.

Значение по умолчанию — Disabled.The default is Disabled.
KeyStoreAuthentication Допустимые значения: KeyVaultPassword, KeyVaultClientSecretValid Values: KeyVaultPassword, KeyVaultClientSecret
KeyStorePrincipalId Если KeyStoreAuthentication = KeyVaultPassword, укажите здесь допустимое имя участника-пользователя (UPN) Azure Active Directory.When KeyStoreAuthentication = KeyVaultPassword, set this value to a valid Azure Active Directory User Principal Name.
Если KeyStoreAuthetication = KeyVaultClientSecret, укажите здесь допустимый идентификатор клиента приложения Azure Active Directory.When KeyStoreAuthetication = KeyVaultClientSecret set this value to a valid Azure Active Directory Application Client ID
KeyStoreSecret Если KeyStoreAuthentication = KeyVaultPassword, укажите здесь пароль для соответствующего имени пользователя.When KeyStoreAuthentication = KeyVaultPassword set this value to the password for the corresponding user name.
Если KeyStoreAuthentication = KeyVaultClientSecret, укажите здесь секрет приложения, связанный с допустимым идентификатором клиента приложения Azure Active Directory.When KeyStoreAuthentication = KeyVaultClientSecret set this value to the Application Secret associated with a valid Azure Active Directory Application Client ID

Атрибуты соединенияConnection Attributes

ИмяName ТипType ОписаниеDescription
SQL_COPT_SS_COLUMN_ENCRYPTION Перед подключениемPre-connect SQL_COLUMN_ENCRYPTION_DISABLE (0) — функция Always Encrypted отключенаSQL_COLUMN_ENCRYPTION_DISABLE (0) -- Disable Always Encrypted
SQL_COLUMN_ENCRYPTION_ENABLE (1) — функция Always Encrypted включенаSQL_COLUMN_ENCRYPTION_ENABLE (1) -- Enable Always Encrypted
Указатель на тип, строкаданных (версия 17,4 и более поздние) включить с защитой анклаваpointer to type,data string -- (version 17.4 and later) enable with secure enclave
SQL_COPT_SS_CEKEYSTOREPROVIDER После подключенияPost-connect [Set] Пытается загрузить CEKeystoreProvider[Set] Attempt to load CEKeystoreProvider
[Get] Возвращает имя CEKeystoreProvider[Get] Return a CEKeystoreProvider name
SQL_COPT_SS_CEKEYSTOREDATA После подключенияPost-connect [Set] Запись данных в CEKeystoreProvider[Set] Write data to CEKeystoreProvider
[Get] Чтение данных из CEKeystoreProvider[Get] Read data from CEKeystoreProvider
SQL_COPT_SS_CEKCACHETTL После подключенияPost-connect [Set] Указание срока жизни для ключей CEK в кэше[Set] Set the CEK cache TTL
[Set] Получение текущего значения срока жизни для ключей CEK в кэше[Get] Get the current CEK cache TTL
SQL_COPT_SS_TRUSTEDCMKPATHS После подключенияPost-connect [Set] Сохранение указателя на доверенные пути CMK[Set] Set the trusted CMK paths pointer
[Get] Получение текущего указателя на доверенные пути CMK[Get] Get the current trusted CMK paths pointer

Атрибуты инструкцииStatement Attributes

ИмяName ОписаниеDescription
SQL_SOPT_SS_COLUMN_ENCRYPTION SQL_CE_DISABLED (0) — функция Always Encrypted отключена для инструкции.SQL_CE_DISABLED (0) -- Always Encrypted is disabled for the statement
SQL_CE_RESULTSETONLY (1) — только расшифровка.SQL_CE_RESULTSETONLY (1) -- Decryption Only. Расшифровываются результирующие наборы и возвращаемые значения, а параметры не шифруются.Resultsets and return values are decrypted, and parameters are not encrypted
SQL_CE_ENABLED (3) — функция Always Encrypted включена и используется как для параметров, так и для результатов.SQL_CE_ENABLED (3) -- Always Encrypted is enabled and used for both parameters and results

Поля дескриптораDescriptor Fields

Поле дескриптора параметра реализации (IPD)IPD Field Размер и типSize/Type Значение по умолчаниюDefault Value ОписаниеDescription
SQL_CA_SS_FORCE_ENCRYPT (1236)SQL_CA_SS_FORCE_ENCRYPT (1236) Машинное слово (2 байта)WORD (2 bytes) 00 Значение 0 (по умолчанию): решение о шифровании этого параметра определяется наличием метаданных шифрования.When 0 (default): decision to encrypt this parameter is determined by availability of encryption metadata.

Отличное от нуля значение: параметр шифруется, если для него доступны метаданные шифрования.When nonzero: if encryption metadata is available for this parameter, it is encrypted. В противном случае запрос завершается ошибкой [CE300] [Microsoft][ODBC Driver 13 for SQL Server] "Для параметра указано обязательное шифрование, но сервер не предоставил метаданные шифрования".Otherwise, the request fails with error [CE300] [Microsoft][ODBC Driver 13 for SQL Server]Mandatory encryption was specified for a parameter but no encryption metadata was provided by the server.

Параметры bcp_controlbcp_control Options

Имя параметраOption Name Значение по умолчаниюDefault Value ОписаниеDescription
BCPMODIFYENCRYPTED (21)BCPMODIFYENCRYPTED (21) FALSEFALSE Если значение равно TRUE, в зашифрованный столбец можно вставлять значения в формате varbinary(max).When TRUE, allows varbinary(max) values to be inserted into an encrypted column. Если значение равно FALSE, вставка не допускается без указания правильных метаданных типа и шифрования.When FALSE, prevents insertion unless correct type and encryption metadata is supplied.

См. также:See Also