Partilhar via


Usando Always Encrypted com os Drivers PHP para SQL Server

Descarregar o driver PHP

Aplicável a

  • Microsoft Drivers 5.2 para PHP para SQL Server

Introdução

Este artigo fornece informações sobre como desenvolver aplicações PHP usando o Always Encrypted (Motor de Base de Dados) e os drivers PHP para SQL Server.

O Always Encrypted permite que aplicações clientes encriptem dados sensíveis e nunca revelem os dados ou as chaves de encriptação ao SQL Server ou Azure SQL Database. Um driver ativado pelo Always Crypted, como o ODBC Driver for SQL Server, encripta e desencripta de forma transparente dados sensíveis na aplicação cliente. O driver determina automaticamente quais os parâmetros de consulta que correspondem a colunas sensíveis da base de dados (protegidas com o Always Encrypted) e encripta os valores desses parâmetros antes de passar os dados para o SQL Server ou Azure SQL Database. De forma semelhante, o driver desencripta de forma transparente os dados recuperados das colunas da base de dados encriptadas nos resultados das consultas. Para mais informações, consulte Always Encrypted (Motor de Base de Dados). Os drivers PHP para SQL Server utilizam o driver ODBC para SQL Server para encriptar dados sensíveis.

Pré-requisitos

  • Configure Sempre Encriptado na sua base de dados. Esta configuração envolve o provisionamento de chaves Always Encrypted e a configuração de encriptação para colunas selecionadas da base de dados. Se ainda não tiver uma base de dados com o Always Encrypted configurado, siga as instruções no Tutorial: Como começar com o Always Encrypted. Em particular, a sua base de dados deve conter as definições de metadados para uma Chave Mestra de Coluna (CMK), uma Chave de Encriptação de Coluna (CEK) e uma tabela contendo uma ou mais colunas encriptadas usando essa CEK.
  • Certifique-se de que o ODBC Driver para SQL Server versão 17 ou superior está instalado na sua máquina de desenvolvimento. Para detalhes, consulte ODBC Driver for SQL Server.

Ativar o Always Encrypted numa aplicação PHP

A forma mais fácil de ativar a encriptação dos parâmetros que visam as colunas encriptadas e a desencriptação dos resultados das consultas é definir o valor da ColumnEncryption palavra-chave da cadeia de ligação para Enabled. Seguem-se exemplos de ativação do Always Encrypted nos drivers SQLSRV e 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);

Ativar o Always Encrypted não é suficiente para que a encriptação ou a desencriptação tenham sucesso; Também precisa de garantir que:

  • A aplicação tem as permissões VIEW ANY COLUMN MASTER KEY DEFINITION e VIEW ANY COLUMN ENCRYPTION KEY DEFINITION, necessárias para acessar os metadados sobre chaves Always Encrypted na base de dados. Para mais detalhes, consulte Permissão para a Base de Dados.
  • A aplicação pode aceder ao CMK que protege os CEKs das colunas cifradas consultadas. Este requisito depende do fornecedor de armazenamento chave que armazena o CMK. Para mais informações, consulte Trabalhar com Repositórios de Chaves Mestras de Colunas.

Recuperação e modificação de dados em colunas encriptadas

Depois de ativar o Always Encrypted numa conexão, pode usar as APIs padrão SQLSRV (ver Referência de API do Driver SQLSRV) ou as APIs PDO_SQLSRV (ver Referência de API do Driver PDO_SQLSRV) para recuperar ou modificar dados em colunas de bases de dados encriptadas. Assumindo que a sua aplicação tem as permissões necessárias para a base de dados e pode aceder à chave mestra da coluna, o driver encripta quaisquer parâmetros de consulta que visem colunas encriptadas e desencriptem dados recuperados de colunas encriptadas, comportando-se de forma transparente para a aplicação como se as colunas não estivessem encriptadas.

Se o Always Encrypted não estiver ativado, consultas com parâmetros que visam colunas encriptadas falham. Os dados ainda podem ser recuperados de colunas encriptadas, desde que a consulta não tenha parâmetros direcionados a colunas encriptadas. No entanto, o driver não tenta qualquer desencriptação e a aplicação recebe os dados encriptados binários (como arrays de bytes).

A tabela seguinte resume o comportamento das consultas, dependendo se o Always Encrypted está ativado ou não:

Característica da consulta Always Encrypted está ativado e o aplicativo pode acessar as chaves e metadados de chave O Always Encrypted está ativado e a aplicação não consegue aceder às chaves ou aos metadados das chaves O Always Encrypted está desativado
Parâmetros aplicados a colunas cifradas. Os valores dos parâmetros são encriptados de forma transparente. Erro Erro
Recuperar dados de colunas encriptadas, sem parâmetros que visem colunas encriptadas. Os resultados das colunas encriptadas são desencriptados de forma transparente. A aplicação recebe valores de colunas em texto simples. Erro Os resultados das colunas encriptadas não são desencriptados. A aplicação recebe valores encriptados como arrays de bytes.

Os exemplos seguintes ilustram a recuperação e modificação de dados em colunas encriptadas. Os exemplos assumem uma tabela com o seguinte esquema. As colunas SSN e Data de Nascimento estão encriptadas.

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

Exemplo de inserção de dados

Os exemplos seguintes demonstram como usar os drivers SQLSRV e PDO_SQLSRV para inserir uma linha na tabela Patient. Observe os seguintes pontos:

  • Não há nada específico para criptografia no código de exemplo. O driver deteta e encripta automaticamente os valores dos parâmetros SSN e BirthDate, que têm como alvo colunas encriptadas. Este mecanismo torna a encriptação transparente para a aplicação.
  • Os valores inseridos nas colunas da base de dados, incluindo as colunas encriptadas, são passados como parâmetros limitados. Embora usar parâmetros seja opcional ao enviar valores para colunas não encriptadas (embora seja altamente recomendado porque ajuda a prevenir a injeção SQL), é obrigatório para valores que visam colunas encriptadas. Se os valores inseridos nas colunas SSN ou Data de Nascimento fossem passados como literais incorporados na instrução da consulta, a consulta falharia porque o driver não tenta encriptar ou processar literais nas consultas. Como resultado, o servidor os rejeitaria como incompatíveis com as colunas criptografadas.
  • Ao inserir valores usando parâmetros de ligação, um tipo SQL idêntico ao tipo de dados da coluna de destino ou cuja conversão para o tipo de dado da coluna de destino é suportada deve ser passado para a base de dados. Este requisito deve-se ao facto de o Always Encrypted suportar poucas conversões de tipos (para mais detalhes, ver Always Encrypted (Database Engine)). Os dois drivers PHP, SQLSRV e PDO_SQLSRV, têm cada um um mecanismo para ajudar o utilizador a determinar o tipo SQL do valor. Assim, o utilizador não tem de fornecer explicitamente o tipo SQL.
    • Para o driver SQLSRV, o utilizador tem duas opções:
      • Confie no driver PHP para determinar e definir o tipo de SQL correto. Neste caso, o utilizador deve usar sqlsrv_prepare e sqlsrv_execute executar uma consulta parametrizada.
      • Define explicitamente o tipo SQL.
    • Para o driver PDO_SQLSRV, o utilizador não pode definir explicitamente o tipo SQL de um parâmetro. O driver PDO_SQLSRV ajuda automaticamente o utilizador a determinar o tipo SQL ao associar um parâmetro.
  • Para que os drivers possam determinar o tipo SQL, aplicam-se algumas limitações:
    • Driver SQLSRV:
      • Se o utilizador quiser que o driver determine os tipos SQL para as colunas encriptadas, deve usar sqlsrv_prepare e sqlsrv_execute.
      • Se sqlsrv_query for preferido, o utilizador é responsável por especificar os tipos SQL para todos os parâmetros. O tipo SQL especificado deve incluir o comprimento da cadeia para os tipos de cadeia, e a escala e precisão para os tipos decimais.
    • PDO_SQLSRV Driver:
      • O atributo de instrução PDO::SQLSRV_ATTR_DIRECT_QUERY não é suportado numa consulta parametrizada.
      • O atributo PDO::ATTR_EMULATE_PREPARES da declaração não é suportado numa consulta parametrizada.

Driver SQLSRV e 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);

Driver SQLSRV e 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 driver e 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();

Exemplo de recuperação de dados em texto simples

Os exemplos seguintes demonstram filtrar dados com base em valores encriptados e recuperar dados de texto simples de colunas encriptadas usando os drivers SQLSRV e PDO_SQLSRV. Observe os seguintes pontos:

  • O valor usado na cláusula WHERE para filtrar na coluna SSN precisa de ser passado usando o parâmetro de ligar, para que o driver possa encriptá-lo de forma transparente antes de o enviar para o servidor.
  • Ao executar uma consulta com parâmetros limitados, os drivers PHP determinam automaticamente o tipo SQL para o utilizador, a menos que o utilizador especifique explicitamente o tipo SQL ao usar o driver SQLSRV.
  • Todos os valores impressos pelo programa são em texto simples, uma vez que o driver desencripta de forma transparente os dados recuperados das colunas SSN e Data de Nascimento.

Observação

As consultas só podem realizar comparações de igualdade em colunas encriptadas se a encriptação for determinística.

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 = "SELECT [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();

Exemplo de recuperação de dados em texto cifrado

Se o Always Encrypted não estiver ativado, uma consulta ainda pode recuperar dados de colunas encriptadas, desde que a consulta não tenha parâmetros direcionados a colunas encriptadas.

Os exemplos seguintes ilustram a recuperação de dados binários encriptados de colunas encriptadas usando os drivers SQLSRV e PDO_SQLSRV. Observe os seguintes pontos:

  • Como o Always Encrypted não está ativado na cadeia de ligação, a consulta devolve valores encriptados de SSN e BirthDate como arrays de bytes (o programa converte os valores em strings).
  • Uma consulta que recupera dados de colunas criptografadas com Always Encrypted desabilitado pode ter parâmetros, desde que nenhum dos parâmetros tenha como alvo uma coluna criptografada. A consulta a seguir filtra por LastName, que não é criptografado no banco de dados. Se a consulta filtrar por SSN ou Data de Nascimento, a consulta falharia.

SQLSRV:

$query = "SELECT [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 = "SELECT [SSN], [FirstName], [LastName], [BirthDate] FROM [dbo].[Patients] WHERE [LastName] = ?";
$lastName = "Abel";
$stmt = $conn->prepare($query);
$stmt->bindParam(1, $lastName);
$stmt->execute();
$row = $stmt->fetch();

Evitar problemas comuns ao consultar colunas encriptadas

Esta secção descreve categorias comuns de erros ao consultar colunas encriptadas de aplicações PHP e algumas orientações sobre como os evitar.

Erros de conversão de tipos de dados não suportados

O Always Encrypted suporta poucas conversões para tipos de dados encriptados. Consulte Always Encrypted (Motor de Base de Dados) para a lista detalhada de conversões de tipos suportadas. Faça o seguinte para evitar erros de conversão de tipos de dados:

  • Ao usar o driver SQLSRV com sqlsrv_prepare e sqlsrv_execute o tipo SQL, juntamente com o tamanho da coluna e o número de dígitos decimais do parâmetro é determinado automaticamente.
  • Ao usar o driver PDO_SQLSRV para executar uma consulta, o tipo SQL com o tamanho da coluna e o número de dígitos decimais do parâmetro também é automaticamente determinado
  • Ao usar o driver SQLSRV com sqlsrv_query para executar uma consulta:
    • O tipo SQL do parâmetro é exatamente igual ao tipo da coluna alvo, ou a conversão do tipo SQL para o tipo da coluna é suportada.
    • A precisão e a escala dos parâmetros que direcionam colunas dos tipos de dados SQL Server são iguais à precisão e escala configuradas para a coluna de destino.
    • A precisão dos parâmetros que direcionam colunas de datetime2, datetimeoffset, ou time tipos de dados SQL Server não é maior do que a precisão da coluna de destino, em consultas que modificam a coluna de destino.
  • Não use atributos de instrução PDO::SQLSRV_ATTR_DIRECT_QUERY PDO_SQLSRV ou PDO::ATTR_EMULATE_PREPARES numa consulta parametrizada

Erros devido à passagem de texto simples em vez de valores encriptados

Qualquer valor que tenha como alvo uma coluna encriptada precisa de ser encriptado antes de ser enviado para o servidor. Uma tentativa de inserir, modificar ou filtrar por um valor de texto simples numa coluna encriptada resulta num erro. Para evitar tais erros, certifique-se de que:

  • Sempre Encriptado está ativado (na cadeia de ligação, defina a ColumnEncryption palavra-chave para Enabled).
  • Usas o parâmetro de ligação para enviar dados direcionados a colunas encriptadas. O exemplo seguinte mostra uma consulta que é filtrada incorretamente por um literal/constante numa coluna cifrada (Número de Segurança Social - SSN):
$query = "SELECT [SSN], [FirstName], [LastName], [BirthDate] FROM [dbo].[Patients] WHERE SSN='795-73-9838'";

Controlar o impacto no desempenho do Always Encrypted

Como o Always Encrypted é uma tecnologia de criptografia do lado do cliente, a maior parte da sobrecarga de desempenho é observada no lado do cliente, não no banco de dados. Para além do custo das operações de encriptação e desencriptação, as outras fontes de sobrecarga de desempenho do lado do cliente são:

  • Interações adicionais com a base de dados para obter metadados para os parâmetros de consulta.
  • Chamadas a um armazenamento de chave mestra de coluna para aceder à mesma.

Viagens de ida e volta para recuperar metadados para parâmetros de consulta

Se o Always Encrypted estiver ativado para uma ligação, o Driver ODBC chamará, por defeito, sys.sp_describe_parameter_encryption para cada consulta parametrizada, passando a instrução de consulta (sem quaisquer valores de parâmetro) para o SQL Server. Este procedimento armazenado analisa a instrução de consulta para determinar se algum parâmetro precisa de ser encriptado e, em caso afirmativo, devolve a informação relacionada com a encriptação de cada parâmetro para permitir que o driver os encripte.

Como os drivers PHP permitem ao utilizador associar um parâmetro numa instrução preparada sem fornecer o tipo SQL, ao ligar um parâmetro numa ligação com Always Crypted, os drivers PHP chamam SQLDescribeParam no parâmetro para obter o tipo SQL, o tamanho da coluna e os dígitos decimais. Os metadados são então usados para chamar o SQLBindParameter. Estas chamadas adicionais SQLDescribeParam não requerem idas e vindas adicionais à base de dados, pois o driver ODBC já armazenou as informações do lado do cliente quando sys.sp_describe_parameter_encryption foi chamado.

Os comportamentos anteriores garantem um elevado nível de transparência para a aplicação cliente (e para o programador da aplicação) que não precisa de saber quais consultas acedem às colunas encriptadas, desde que os valores direcionados às colunas encriptadas sejam passados ao driver em parâmetros.

Ao contrário do ODBC Driver para SQL Server, ativar o Always Encrypted ao nível de instruções/query ainda não é suportado nos drivers PHP.

Cache de chaves de encriptação de colunas

Para reduzir o número de chamadas para um armazenamento de chaves mestras de coluna para desencriptar chaves de encriptação de coluna (CEK), o driver armazena em cache os CEKs em texto plano na memória. Após receber o CEK encriptado (ECEK) a partir dos metadados da base de dados, o driver ODBC tenta primeiro encontrar o CEK em texto simples correspondente ao valor da chave encriptada na cache. O driver chama o armazenamento de chaves que contém a CMK apenas se não conseguir encontrar o CEK em texto simples correspondente na cache.

Nota: No Driver ODBC para SQL Server, as entradas na cache são eliminadas após um timeout de duas horas. Este comportamento significa que, para um determinado ECEK, o driver contacta o repositório de chaves apenas uma vez durante a duração de vida da aplicação ou a cada duas horas, o que ocorrer primeiro.

Trabalhar com repositórios de Column Master Key

Para encriptar ou desencriptar dados, o driver precisa de obter um CEK configurado para a coluna de destino. Os CEKs são armazenados em forma encriptada (ECEKs) nos metadados da base de dados. Cada CEK tem uma CMK correspondente que foi usada para a encriptar. Os metadados da base de dados não armazenam o CMK em si; contém apenas o nome do armazenamento de chaves e informações que o armazenamento de chaves pode usar para localizar o CMK.

Para obter o valor em texto simples de um ECEK, o driver obtém primeiro os metadados tanto sobre o CEK como sobre o respetivo CMK, e depois usa essa informação para contactar o armazenamento de chaves que contém o CMK e solicitar-lhe que descifre o ECEK. O condutor comunica com um depósito de chaves através de um fornecedor de armazenamento de chaves.

Para o Microsoft Driver 5.3.0 para PHP para SQL Server, apenas o Windows Certificate Store Provider e o Azure Key Vault são suportados. O outro Keystore Provider suportado pelo ODBC Driver (Custom Keystore Provider) ainda não é suportado.

Utilização do fornecedor da Windows Certificate Store

O Driver ODBC para SQL Server no Windows inclui um fornecedor de armazenamento de chaves mestras em coluna incorporado para o Windows Certificate Store, chamado MSSQL_CERTIFICATE_STORE. (Este fornecedor não está disponível no macOS ou Linux.) Com este fornecedor, o CMK é armazenado localmente na máquina cliente e não é necessária nenhuma outra configuração da aplicação para o usar com o driver. No entanto, a aplicação deve ter acesso ao certificado e à sua chave privada na loja. Para mais informações, consulte Criar e Armazenar Chaves Mestras de Coluna (Sempre Encriptadas).

Usando Azure Key Vault

O Azure Key Vault oferece uma forma de armazenar chaves de encriptação, palavras-passe e outros segredos através do Azure e pode ser usado para armazenar chaves do Always Encrypted. O ODBC Driver para SQL Server (versão 17 e superiores) inclui um fornecedor de armazenamento de chaves mestras incorporado para o Azure Key Vault. As seguintes opções de ligação tratam da configuração do Azure Key Vault: KeyStoreAuthentication, KeyStorePrincipalId, e KeyStoreSecret.

  • KeyStoreAuthentication pode assumir um de dois valores possíveis de cadeia: KeyVaultPassword e KeyVaultClientSecret. Estes valores controlam que tipo de credenciais de autenticação são usadas com as outras duas palavras-chave.
  • KeyStorePrincipalId recebe uma string que representa um identificador da conta que pretende aceder ao Azure Key Vault.
    • Se KeyStoreAuthentication for definido como KeyVaultPassword, então KeyStorePrincipalId deve ser o nome de um utilizador do Microsoft Entra.
    • Se KeyStoreAuthentication estiver definido como KeyVaultClientSecret, então KeyStorePrincipalId deve ser um ID de cliente de aplicação.
  • KeyStoreSecret Recebe uma cadeia de caracteres que representa um segredo de autenticidade.
    • Se KeyStoreAuthentication for definido para KeyVaultPassword, então KeyStoreSecret deve ser a palavra-passe do utilizador.
    • Se KeyStoreAuthentication for definido como KeyVaultClientSecret, então KeyStoreSecret deve ser o segredo da aplicação associado ao ID do cliente da aplicação.

As três opções devem estar presentes na string de ligação para usar o Azure Key Vault. Além disso, ColumnEncryption deve ser definido para Enabled. Se ColumnEncryption estiver definido para Disabled mas as opções Azure Key Vault estiverem presentes, o script continuará sem erros, mas não será realizada encriptação.

Os exemplos seguintes mostram como se ligar ao SQL Server usando o Azure Key Vault.

SQLSRV:

Usar uma conta Microsoft Entra:

$connectionInfo = array("Database"=>$databaseName, "UID"=>$uid, "PWD"=>$pwd, "ColumnEncryption"=>"Enabled", "KeyStoreAuthentication"=>"KeyVaultPassword", "KeyStorePrincipalId"=>$MSEntraUsername, "KeyStoreSecret"=>$MSEntraPassword);
$conn = sqlsrv_connect($server, $connectionInfo);

Usar um ID de cliente e segredo de uma aplicação do Azure:

$connectionInfo = array("Database"=>$databaseName, "UID"=>$uid, "PWD"=>$pwd, "ColumnEncryption"=>"Enabled", "KeyStoreAuthentication"=>"KeyVaultClientSecret", "KeyStorePrincipalId"=>$applicationClientID, "KeyStoreSecret"=>$applicationClientSecret);
$conn = sqlsrv_connect($server, $connectionInfo);

PDO_SQLSRV: Utilização de uma conta Microsoft Entra:

$connectionInfo = "Database = $databaseName; ColumnEncryption = Enabled; KeyStoreAuthentication = KeyVaultPassword; KeyStorePrincipalId = $AADUsername; KeyStoreSecret = $AADPassword;";
$conn = new PDO("sqlsrv:server = $server; $connectionInfo", $uid, $pwd);

Usando um ID de cliente e segredo de aplicação Azure:

$connectionInfo = "Database = $databaseName; ColumnEncryption = Enabled; KeyStoreAuthentication = KeyVaultClientSecret; KeyStorePrincipalId = $applicationClientID; KeyStoreSecret = $applicationClientSecret;";
$conn = new PDO("sqlsrv:server = $server; $connectionInfo", $uid, $pwd);

Limitações dos drivers PHP ao usar o Always Encrypted

SQLSRV e PDO_SQLSRV:

  • Linux/macOS não suportam o Provedor de Armazenamento de Certificados do Windows
  • Forçar a encriptação dos parâmetros
  • Ativar o Always Encrypted ao nível da instrução
  • Ao usar a funcionalidade Always Encrypted e locais não UTF8 no Linux e macOS (como "en_US. ISO-8859-1"), inserir dados nulos ou uma cadeia vazia numa coluna char(n) encriptada pode não funcionar a menos que a Página de Códigos 1252 tenha sido instalada no seu sistema

Apenas SQLSRV:

  • Usar sqlsrv_query para ligação de parâmetros sem especificar o tipo SQL
  • Utilização sqlsrv_prepare de parâmetros de ligação num lote de instruções SQL

PDO_SQLSRV apenas:

  • PDO::SQLSRV_ATTR_DIRECT_QUERY atributo de instrução especificado numa consulta parametrizada
  • PDO::ATTR_EMULATE_PREPARE atributo de instrução especificado numa consulta parametrizada
  • parâmetros de ligação num lote de instruções SQL

Os drivers PHP também herdam as limitações impostas pelo ODBC Driver para SQL Server e pela base de dados. Consulte Limitações do driver ODBC ao utilizar Sempre Encriptado e limitações do Sempre Encriptado.

Consulte também

Guia de Programação para o Driver SQL PHP
Referência da API do Driver SQLSRV
Referência da API do Driver PDO_SQLSRV