Использование функции Always Encrypted с драйверами PHP для SQL Server
Применимо к
- Драйверы Майкрософт версии 5.2 для PHP для SQL Server
Введение
В этой статье описано, как разрабатывать приложения PHP с помощью драйвера PHP Driver for SQL Server с Always Encrypted (ядро СУБД).
Функция Always Encrypted позволяет шифровать конфиденциальные данные в клиентских приложениях, не раскрывая данные или ключи шифрования для SQL Server или Базы данных SQL Azure. Драйвер с поддержкой Always Encrypted, такой как драйвер OLE DB для SQL Server, выполняет прозрачное шифрование и расшифровку конфиденциальных данных в клиентском приложении. Драйвер автоматически определяет, какие параметры запроса соответствуют важным столбцам базы данных (защищенным с помощью Always Encrypted), и шифрует значения этих параметров перед передачей данных в SQL Server или Базу данных SQL Azure. Аналогичным образом драйвер прозрачно расшифровывает данные, полученные из зашифрованных столбцов базы в результатах запроса. Дополнительные сведения см. в разделе Always Encrypted (ядро СУБД). Драйверы PHP для SQL Server используют драйвер ODBC для SQL Server, чтобы шифровать конфиденциальные данные.
Необходимые компоненты
- Настройте функцию постоянного шифрования в базе данных. В процесс настройки входят действия по подготовке ключей Always Encrypted и настройке шифрования для выбранных столбцов базы данных. Если у вас еще нет базы данных с настроенным Always Encrypted, следуйте инструкциям в руководстве по началу работы с Always Encrypted. В частности база данных должна содержать определения метаданных для главного ключа столбца (CMK), ключа шифрования столбца (CEK) и таблицы с одним или несколькими столбцами, зашифрованными с помощью этого ключа CEK.
- Убедитесь, что на компьютере, предназначенном для разработки, установлен драйвер ODBC версии 17 или более поздней. Дополнительные сведения см. в статье Microsoft ODBC Driver for SQL Server.
Включение функции Always Encrypted в приложении PHP
Самым простым способом включения шифрования параметров для зашифрованных столбцов и расшифровки результатов запросов является установка для ключевого слова строки подключения ColumnEncryption
значения Enabled
. Ниже приведены примеры включения функции Always Encrypted в драйверах SQLSRV и PDO_SQLSRV.
SQLSRV:
$connectionInfo = array("Database"=>$databaseName, "UID"=>$uid, "PWD"=>$pwd, "ColumnEncryption"=>"Enabled");
$conn = sqlsrv_connect($server, $connectionInfo);
PDO_SQLSRV:
$connectionInfo = "Database = $databaseName; ColumnEncryption = Enabled;";
$conn = new PDO("sqlsrv:server = $server; $connectionInfo", $uid, $pwd);
Включенной функции Always Encrypted недостаточно для успешного шифрования или расшифровки. Вам нужно убедиться в следующем:
- Приложение имеет разрешения VIEW ANY COLUMN MASTER KEY DEFINITION и VIEW ANY COLUMN ENCRYPTION KEY DEFINITION для базы данных, необходимые для доступа к метаданным о ключах постоянного шифрования в базе данных. См. подробнее о разрешениях базы данных.
- Приложение может обращаться к CMK для защиты ключей CEK для запрашиваемых зашифрованных столбцов. Это требование зависит от поставщика хранилища ключей, который хранит CMK. См. подробнее о работе с хранилищами главных ключей столбцов.
Получение и изменение данных в зашифрованных столбцах
Включив Always Encrypted для подключения, вы можете использовать стандартные API-интерфейсы SQLSRV (см. справочник по API для драйвера SQLSRV) или API-интерфейсы PDO_SQLSRV (см. справочник по драйверу PDO_SQLSRV) для извлечения или изменения данных в зашифрованных столбцах базы данных. Если приложение имеет необходимые разрешения для базы данных и может обращаться к главному ключу столбца, драйвер будет шифровать все параметры запроса, затрагивающие зашифрованные столбцы, и расшифровывать данные, извлекаемые из зашифрованных столбцов. Для приложения это все выполняется незаметно, как если бы столбцы не были зашифрованы.
Если функция Always Encrypted не включена, выполнение запросов с параметрами, предназначенными для зашифрованных столбцов, завершится ошибкой. Данные по-прежнему могут извлекаться из зашифрованных столбцов, пока для них не будут указаны параметры, предназначенные для зашифрованных столбцов. При этом драйвер не будет применять расшифровку, и приложение будет получать двоичные зашифрованные данные (в виде массивов байтов).
В приведенной ниже таблице описывается поведение запросов в зависимости от того, включена ли функция Always Encrypted:
Характеристика запроса | Постоянное шифрование включено, и приложение может получать доступ к ключам и метаданным ключей | Функция Always Encrypted включена, и приложение не может получать доступ к ключам и метаданным ключей | Постоянное шифрование отключено |
---|---|---|---|
Параметры, предназначенные для зашифрованных столбцов. | Значения параметров прозрачно шифруются. | Ошибка | Ошибка |
Извлечение данных из зашифрованных столбцов без параметров, предназначенных для зашифрованных столбцов. | Результаты из зашифрованных столбцов прозрачно расшифровываются. Приложение получает значения столбца в виде обычного текста. | Ошибка | Результаты из зашифрованных столбцов не расшифровываются. Приложение получает зашифрованные значения в виде массивов байтов. |
В следующих примерах показано получение и изменение данных в зашифрованных столбцах. В этом примере предполагается, что таблица имеет следующую схему. Столбцы 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
Пример вставки данных
В следующих примерах показано, как использовать драйверы SQLSRV и PDO_SQLSRV для вставки строки в таблицу Patient (Пациент). Обратите внимание на следующие аспекты:
- В примере кода нет ничего, связанного с шифрованием. Драйвер автоматически обнаруживает и шифрует значения параметров SSN и BirthDate, которые предназначены для зашифрованных столбцов. В этом случае шифрование является прозрачным для приложения.
- Значения, вставляемые в столбцы базы данных, включая зашифрованные столбцы, передаются как связанные параметры. Несмотря на то, что при отправке значений в незашифрованные столбцы использовать параметры необязательно (но настоятельно рекомендуется, так как это помогает предотвратить внедрение кода SQL), они требуются для значений, предназначенных для зашифрованных столбцов. Если значения, вставленные в столбцы SSN или BirthDate, были переданы в качестве внедренных в инструкцию запроса литералов, выполнение запроса завершится ошибкой, так как драйвер не пытается шифровать или иным образом обрабатывать литералы в запросах. В результате сервер отклонит их как несовместимые с зашифрованными столбцами.
- При вставке значений с использованием параметров привязки в базу данных должен передаваться тип SQL, идентичный типу данных целевого столбца или типу, для которого поддерживается преобразование в тип данных целевого столбца. Это требование обусловлено тем, что Always Encrypted поддерживает несколько преобразований типов (дополнительные сведения см. в этой статье). Два драйвера PHP, SQLSRV и PDO_SQLSRV, имеют механизм, помогающий пользователю определить тип значения SQL. Таким образом, пользователю не нужно явно предоставлять тип SQL.
- Для драйвера SQLSRV у пользователя есть два варианта:
- Пользователь может использовать драйвер PHP, чтобы определить и установить правильный тип SQL. В этом случае для выполнения параметризованного запроса пользователь должен использовать
sqlsrv_prepare
иsqlsrv_execute
. - Пользователь может явно задать тип SQL.
- Пользователь может использовать драйвер PHP, чтобы определить и установить правильный тип SQL. В этом случае для выполнения параметризованного запроса пользователь должен использовать
- Для драйвера PDO_SQLSRV пользователь не может явно задавать тип SQL параметра. Драйвер PDO_SQLSRV автоматически помогает пользователю определить тип SQL при привязке параметра.
- Для драйвера SQLSRV у пользователя есть два варианта:
- Чтобы определить тип SQL, применяются некоторые ограничения:
- Драйвер SQLSRV:
- Если пользователь хочет, чтобы драйвер определил типы SQL для зашифрованных столбцов, пользователь должен использовать
sqlsrv_prepare
иsqlsrv_execute
. - Если
sqlsrv_query
является предпочтительным, пользователь несет ответственность за указание типов SQL для всех параметров. Указанный тип SQL должен включать длину строки для строковых типов, а также масштаб и точность для десятичных типов.
- Если пользователь хочет, чтобы драйвер определил типы SQL для зашифрованных столбцов, пользователь должен использовать
- драйвер PDO_SQLSRV:
- Атрибут инструкции
PDO::SQLSRV_ATTR_DIRECT_QUERY
не поддерживается для параметризованного запроса. - Атрибут инструкции
PDO::ATTR_EMULATE_PREPARES
не поддерживается для параметризованного запроса.
- Атрибут инструкции
- Драйвер SQLSRV:
Драйвер SQLSRV и sqlsrv_prepare:
// insertion into encrypted columns must use a parameterized query
$query = "INSERT INTO [dbo].[Patients] ([SSN], [FirstName], [LastName], [BirthDate]) VALUES (?, ?, ?, ?)";
$ssn = "795-73-9838";
$firstName = "Catherine";
$lastName = "Abel;
$birthDate = "1996-10-19";
$params = array($ssn, $firstName, $lastName, $birthDate);
// during sqlsrv_prepare, the driver determines the SQL types for each parameter and pass them to SQL Server
$stmt = sqlsrv_prepare($conn, $query, $params);
sqlsrv_execute($stmt);
Драйвер SQLSRV и sqlsrv_query:
// insertion into encrypted columns must use a parameterized query
$query = "INSERT INTO [dbo].[Patients] ([SSN], [FirstName], [LastName], [BirthDate]) VALUES (?, ?, ?, ?)";
$ssn = "795-73-9838";
$firstName = "Catherine";
$lastName = "Abel";
$birthDate = "1996-10-19";
// need to provide the SQL types for ALL parameters
// note the SQL types (including the string length) have to be the same at the column definition
$params = array(array(&$ssn, null, null, SQLSRV_SQLTYPE_CHAR(11)),
array(&$firstName, null, null, SQLSRV_SQLTYPE_NVARCHAR(50)),
array(&$lastName, null, null, SQLSRV_SQLTYPE_NVARCHAR(50)),
array(&$birthDate, null, null, SQLSRV_SQLTYPE_DATE));
sqlsrv_query($conn, $query, $params);
Драйвер PDO_SQLSRV и PDO::prepare:
// insertion into encrypted columns must use a parameterized query
$query = "INSERT INTO [dbo].[Patients] ([SSN], [FirstName], [LastName], [BirthDate]) VALUES (?, ?, ?, ?)";
$ssn = "795-73-9838";
$firstName = "Catherine";
$lastName = "Able";
$birthDate = "1996-10-19";
// during PDO::prepare, the driver determines the SQL types for each parameter and pass them to SQL Server
$stmt = $conn->prepare($query);
$stmt->bindParam(1, $ssn);
$stmt->bindParam(2, $firstName);
$stmt->bindParam(3, $lastName);
$stmt->bindParam(4, $birthDate);
$stmt->execute();
Пример получения данных в виде открытого текста
В следующих примерах показана фильтрация данных на основе зашифрованных значений и получение данных в виде открытого текста из зашифрованных столбцов с помощью драйверов SQLSRV и PDO_SQLSRV. Обратите внимание на следующие аспекты:
- Значение, используемое в предложении WHERE для фильтрации по столбцу SSN, необходимо передавать, используя параметр bind, чтобы перед отправкой на сервер драйвер мог его прозрачно зашифровать.
- При выполнении запроса со связанными параметрами драйверы PHP автоматически определяют тип SQL для пользователя, если только пользователь явно не указывает тип SQL при использовании драйвера SQLSRV.
- Все значения, выводимые программой, будут представлены в открытом тексте, так как драйвер прозрачно расшифровывает данные, полученные из столбцов SSN и BirthDate.
Примечание.
Запросы могут выполнять сравнения равенства по зашифрованным столбцам, только если шифрование детерминировано.
SQLSRV:
// since SSN is an encrypted column, need to pass the value in the WHERE clause through bind parameter
$query = "SELECT [SSN], [FirstName], [LastName], [BirthDate] FROM [dbo].[Patients] WHERE [SSN] = ?";
$ssn = "795-73-9838";
$stmt = sqlsrv_prepare($conn, $query, array(&$ssn));
// during sqlsrv_execute, the driver encrypts the ssn value and passes it to the database
sqlsrv_execute($stmt);
// fetch like usual
$row = sqlsrv_fetch_array($stmt);
PDO_SQLSRV:
// since SSN is an encrypted column, need to pass the value in the WHERE clause through bind parameter
$query = "SELET [SSN], [FirstName], [LastName], [BirthDate] FROM [dbo].[Patients] WHERE [SSN] = ?";
$ssn = "795-73-9838";
$stmt = $conn->prepare($query);
$stmt->bindParam(1, $ssn);
// during PDOStatement::execute, the driver encrypts the ssn value and passes it to the database
$stmt->execute();
// fetch like usual
$row = $stmt->fetch();
Пример получения данных в виде зашифрованного текста
Если функция Always Encrypted не включена, запрос может получать данные из зашифрованных столбцов, пока для него не будут указаны параметры, предназначенные для зашифрованных столбцов.
В следующих примерах показано извлечение двоичных зашифрованных данных из зашифрованных столбцов с помощью драйверов SQLSRV и PDO_SQLSRV. Обратите внимание на следующие аспекты:
- Так как функция Always Encrypted не включена в строке подключения, запрос возвращает зашифрованные значения SSN и BirthD в виде байтовых массивов (программа преобразует значения в строки).
- Запрос, получающий данные из зашифрованных столбцов с отключенным постоянным шифрованием, может иметь параметры при условии, что ни один из параметров не предназначен для зашифрованного столбца. Приведенный ниже запрос позволяет выполнить фильтрацию по столбцу LastName, который не зашифрован в базе данных. Запрос, отфильтрованный по SSN или BirthDate, завершится ошибкой.
SQLSRV:
$query = "SELET [SSN], [FirstName], [LastName], [BirthDate] FROM [dbo].[Patients] WHERE [LastName] = ?";
$lastName = "Abel";
$stmt = sqlsrv_prepare($conn, $query, array(&$lastName));
sqlsrv_execute($stmt);
$row = sqlsrv_fetch_array($stmt);
PDO_SQLSRV:
$query = "SELET [SSN], [FirstName], [LastName], [BirthDate] FROM [dbo].[Patients] WHERE [LastName] = ?";
$lastName = "Abel";
$stmt = $conn->prepare($query);
$stmt->bindParam(1, $lastName);
$stmt->execute();
$row = $stmt->fetch();
Как избежать распространенных проблем при запросе зашифрованных столбцов
В этом разделе описываются общие категории ошибок, возникающих при выполнении запросов к зашифрованным столбцам из приложений PHP, и приводятся рекомендации о том, как их избежать.
Ошибки преобразования неподдерживаемых типов данных
Постоянное шифрование поддерживает несколько преобразований для зашифрованных типов данных. Подробный список поддерживаемых преобразований типов см. в статье Always Encrypted (ядро СУБД). Чтобы избежать ошибок при преобразовании типов данных, сделайте следующее:
- При использовании драйвера SQLSRV с
sqlsrv_prepare
иsqlsrv_execute
автоматически определяется тип SQL вместе с размером столбца и количеством десятичных цифр параметра. - При использовании драйвера PDO_SQLSRV для выполнения запроса также автоматически определяется тип SQL вместе с размером столбца и количеством десятичных цифр параметра.
- При использовании драйвера SQLSRV с
sqlsrv_query
выполнением запроса:- Тип SQL для параметра всегда точно совпадает с типом целевого столбца или может быть преобразован в тип этого столбца.
- Точность и масштаб параметров, предназначенных для столбцов типов данных SQL Server
decimal
иnumeric
, соответствуют точности и масштабу, настроенным для конечного столбца. - В запросах, которые изменяют конечный столбец, точность параметров, предназначенных для столбцов типов данных SQL Server
datetime2
,datetimeoffset
илиtime
, не превышает точность для конечного столбца.
- Не используйте атрибуты
PDO::SQLSRV_ATTR_DIRECT_QUERY
илиPDO::ATTR_EMULATE_PREPARES
для инструкции PDO_SQLSRV в параметризованном запросе.
Ошибки, возникающие из-за передачи значений в виде открытого текста, а не в зашифрованном виде
Любое значение, предназначенное для зашифрованного столбца, должно быть зашифровано до отправки на сервер. Попытка вставки, изменения или фильтрации по значению, в виде открытого текста в зашифрованном столбце приведет к возникновению ошибки. Чтобы избежать таких ошибок, убедитесь в том, что:
- Функция Always Encrypted активирована (в строке подключения для ключевого слова
ColumnEncryption
задано значениеEnabled
). - для отправки данных, предназначенных для зашифрованных столбцов, используется параметр bind. В примере ниже показан запрос, который неправильно фильтрует по литералу или константе в зашифрованном столбце (SSN):
$query = "SELET [SSN], [FirstName], [LastName], [BirthDate] FROM [dbo].[Patients] WHERE SSN='795-73-9838'";
Управление влиянием постоянного шифрования на производительность
Так как Always Encrypted является технологией шифрования на стороне клиента, значительное влияние на производительность происходит на стороне клиента, а не в базе данных. Помимо затрат на операции шифрования и расшифровки существуют и другие источники снижения производительности на стороне клиента:
- Дополнительные обращения к базе данных для получения метаданных для параметров запроса.
- Вызовы хранилища главных ключей столбцов для доступа к главному ключу столбца.
Круговые пути для получения метаданных для параметров запроса
Если для соединения включена функция Always Encrypted, по умолчанию драйвер будет вызывать sys.sp_describe_parameter_encryption для каждого параметризованного запроса, передавая инструкцию запроса (без значений параметров) в SQL Server. Эта хранимая процедура анализирует инструкцию запроса и выясняет, нужно ли шифровать параметры. Если да, то она возвращает по каждому параметру связанные с шифрованием сведения, позволяющие драйверу шифровать их.
Так как драйверы PHP позволяют пользователю привязать параметр в подготовленной инструкции без указания типа SQL, то при привязке параметра в подключении с включенным Always Encrypted драйверы PHP вызывают SQLDescribeParam для параметра, чтобы получить тип SQL, размер столбца и десятичные цифры. Затем метаданные используются для вызова SQLBindParameter. Эти дополнительные вызовы SQLDescribeParam
не требуют добавочных обращений к базе данных, так как драйвер ODBC уже сохранил информацию на стороне клиента при вызове sys.sp_describe_parameter_encryption
.
Такое поведение гарантирует для клиентского приложения высокий уровень прозрачности. Так как значения, предназначенные для зашифрованных столбцов, передаются драйверу в параметрах, приложению (и разработчику приложения) не нужно знать, какие запросы обращаются к зашифрованным столбцам.
В отличие от драйвера ODBC для SQL Server включение Always Encrypted на уровне инструкции или запроса пока не поддерживается в драйверах PHP.
Кэширование ключа шифрования столбца
Чтобы уменьшить количество вызовов к хранилищу главных ключей столбцов для расшифровки ключей шифрования столбцов (CEK), драйвер кэширует CEK в памяти в формате открытого текста. Получив зашифрованные CEK (ECEK) из метаданных базы данных, драйвер ODBC сначала пытается найти в кэше CEK в соответствии с зашифрованным значением ключа. Драйвер обращается к хранилищу ключей, где хранится главный ключ столбца, только в том случае, если ему не удается найти в кэше значение CEK в открытом тексте.
Примечание. Драйвер ODBC Driver for SQL Server удаляет записи из этого кэша через два часа. Это означает, что для каждого ECEK драйвер обращается в хранилище ключей только один раз за цикл жизни приложения либо каждые два часа в зависимости от того, что меньше.
Работа с хранилищами главных ключей столбцов
Для шифрования или расшифровки данных драйвер должен получить ключ CEK, который настроен для целевого столбца. Ключи CEK хранятся в зашифрованном виде (ECEK) в метаданных базы данных. Каждому ключу CEK соответствует определенный ключ CMK, который использовался для его шифрования. Метаданные базы данных не хранят значения CMK, а только имя хранилища ключей и информацию для поиска нужных CMK в этом хранилище ключей.
Чтобы получить значение ECEK в формате открытого текста, драйвер сначала получает метаданные о ключах CEK и CMK, а затем на основе этих сведений обращается в хранилище ключей с CMK и запрашивает расшифрованную версию ECEK. Драйвер взаимодействует с хранилищем ключей через поставщик хранилища ключей.
Для драйвера Microsoft Driver 5.3.0 для PHP для SQL Server поддерживаются только поставщик хранилища сертификатов Windows и Azure Key Vault. Этот драйвер пока не поддерживает другой поставщик хранилища ключей, поддерживаемый драйвером ODBC (пользовательский).
Использование поставщика хранилища сертификатов Windows
Драйвер ODBC Driver for SQL Server в Windows содержит встроенный поставщик MSSQL_CERTIFICATE_STORE
хранилища сертификатов Windows для хранения главного ключа. (Этот поставщик недоступен для macOS и Linux.) При использовании этого поставщика ключи CMK хранятся локально на клиентском компьютере, и для его использования с драйвером не нужно вносить никаких других изменений в конфигурацию приложения. Но такому приложению необходимы права доступа к сертификату и закрытому ключу, размещенным в хранилище. Дополнительные сведения см. в разделе Create and Store Column Master Keys (Always Encrypted)(Создание и хранение главных ключей столбцов (постоянное шифрование)).
Использование Azure Key Vault
Azure Key Vault предлагает способ хранения ключей шифрования, паролей и других секретов с помощью Azure и может использоваться для хранения ключей для Always Encrypted. Драйвер ODBC Driver for SQL Server (версии 17 и выше) содержит встроенный поставщик хранилища главных ключей для Azure Key Vault. Конфигурацию Azure Key Vault обрабатывают следующие параметры подключения: KeyStoreAuthentication
, KeyStorePrincipalId
и KeyStoreSecret
.
KeyStoreAuthentication
может принимать одно из двух возможных строковых значений:KeyVaultPassword
иKeyVaultClientSecret
. Эти значения определяют, какой тип учетных данных проверки подлинности используется с другими двумя ключевыми словами.KeyStorePrincipalId
принимает строку, представляющую идентификатор учетной записи, которой требуется доступ к Azure Key Vault.- Если
KeyStoreAuthentication
задано значениеKeyVaultPassword
, тоKeyStorePrincipalId
должно быть именем пользователя Microsoft Entra. - Если для
KeyStoreAuthentication
задано значениеKeyVaultClientSecret
, то значениеKeyStorePrincipalId
должно быть идентификатором клиента приложения.
- Если
KeyStoreSecret
принимает строку, представляющую секрет учетных данных.- Если для
KeyStoreAuthentication
задано значениеKeyVaultPassword
, то значениеKeyStoreSecret
должно быть паролем пользователя. - Если для
KeyStoreAuthentication
задано значениеKeyVaultClientSecret
, то значениеKeyStoreSecret
должно быть секретом приложения, связанным с идентификатором клиента приложения.
- Если для
Для возможности использования Azure Key Vault в строке подключения должны присутствовать все три параметра. Кроме того, для ColumnEncryption
необходимо задать значение Enabled
. Если для ColumnEncryption
задано значение Disabled
, но присутствуют параметры Azure Key Vault, то скрипт продолжит работу без ошибок, но шифрование выполняться не будет.
В следующих примерах показано, как подключиться к SQL Server с помощью Azure Key Vault.
SQLSRV:
Использование учетной записи Microsoft Entra:
$connectionInfo = array("Database"=>$databaseName, "UID"=>$uid, "PWD"=>$pwd, "ColumnEncryption"=>"Enabled", "KeyStoreAuthentication"=>"KeyVaultPassword", "KeyStorePrincipalId"=>$MSEntraUsername, "KeyStoreSecret"=>$MSEntraPassword);
$conn = sqlsrv_connect($server, $connectionInfo);
Использование идентификатора клиента и секрета приложения Azure:
$connectionInfo = array("Database"=>$databaseName, "UID"=>$uid, "PWD"=>$pwd, "ColumnEncryption"=>"Enabled", "KeyStoreAuthentication"=>"KeyVaultClientSecret", "KeyStorePrincipalId"=>$applicationClientID, "KeyStoreSecret"=>$applicationClientSecret);
$conn = sqlsrv_connect($server, $connectionInfo);
PDO_SQLSRV. Использование учетной записи Microsoft Entra:
$connectionInfo = "Database = $databaseName; ColumnEncryption = Enabled; KeyStoreAuthentication = KeyVaultPassword; KeyStorePrincipalId = $AADUsername; KeyStoreSecret = $AADPassword;";
$conn = new PDO("sqlsrv:server = $server; $connectionInfo", $uid, $pwd);
Использование идентификатора клиента и секрета приложения Azure:
$connectionInfo = "Database = $databaseName; ColumnEncryption = Enabled; KeyStoreAuthentication = KeyVaultClientSecret; KeyStorePrincipalId = $applicationClientID; KeyStoreSecret = $applicationClientSecret;";
$conn = new PDO("sqlsrv:server = $server; $connectionInfo", $uid, $pwd);
Ограничения драйвера PHP при использовании Always Encrypted
SQLSRV и PDO_SQLSRV:
- Linux или macOS не поддерживают поставщик хранилища сертификатов Windows.
- Принудительное шифрование параметров
- Включение Always Encrypted на уровне инструкции.
- При использовании функции Always Encrypted и языковых стандартов, отличных от UTF8, в Linux и macOS (например, en_US.ISO-8859-1), вставка данных NULL или пустой строки в зашифрованный столбец типа char(n) может не работать, если в системе не установлена кодовая страница 1252.
Только SQLSRV:
- Использование
sqlsrv_query
для параметра привязки без указания типа SQL. - Использование
sqlsrv_prepare
для привязки параметров в пакете инструкций SQL.
Только PDO_SQLSRV:
- Атрибут инструкции
PDO::SQLSRV_ATTR_DIRECT_QUERY
, указанный в параметризованном запросе. - Атрибут инструкции
PDO::ATTR_EMULATE_PREPARE
, указанный в параметризованном запросе. - Привязанные параметры в пакете инструкций SQL.
Драйверы PHP также наследуют ограничения, установленные драйвером ODBC Driver for SQL Server и базой данных. См. ограничения драйвера ODBC при использовании ограничений Always Encrypted и Always Encrypted.
См. также
Руководство по программированию для драйвера SQL PHP
Справочник по API для драйвера SQLSRV
Справочник по API драйвера PDO_SQLSRV