Recentemente precisei apresentar para um cliente um material com noções básicas dos recursos de criptografia disponíveis no AZURE SQL Database.
Se você já entende os recursos disponíveis no SQL Server 2016 ou superior, aviso que este artigo não vai muito além disso, a não ser talvez pela integração do SQL DATABASE com o KEY VAULT.
Se esse não é o seu caso, apresento a seguir cada um desses recursos, assim como exemplos de implementação.
Encriptação Default dos Serviços Azure
Todos os dados gravados em AZURE, seja em qual serviço for, já dispõem de um nível básico de proteção através da Encriptação em Repouso.
No caso, estamos falando de discos encriptados. Ela usa chaves simétricas, o que significa que tanto a escrita do dado (encriptação) como a leitura dele (decriptação) são feitas usando a mesma chave.
Este tipo de encriptação oferece proteção contra ataques físicos ao hardware (isto é: aos datacenters que proveem os serviços de AZURE).
Para qualquer efeito prático, eu diria que este é o último nível de proteção esperado para os seus dados. Obviamente é muito mais importante para a sua empresa se proteger contra os ataques feitos pela rede. E aí entram os recursos de encriptação para o seu banco de dados.
Encriptação ao Nível de Banco de Dados
Assim como o SQL Server on-premises, o serviço do AZURE SQL DATABASE usa basicamente 03 tipos de criptografia:
- Criptografia de Dados Transparente (TDE)
- ALWAYS ENCRYPTED
- Máscara de Dados Dinâmica (DDM)
Estes métodos são completamente diferentes entre si, pois TDE é uma criptografia aplicada à base de dados inteira, ALWAYS ENCRYPTED trabalha com encriptação ao nível de coluna e DDM, finalmente, não é de fato uma encriptação, mas sim um mascaramento lógico dos dados.
A seguir, apresento mais detalhes de cada método e exemplos de implementação.
Criptografia de Dados Transparente (TDE)
Uma vez que TDE se aplica ao nível de base dados, tudo dentro da base, assim como seus backups, é encriptado.
Naturalmente, os processos de encriptação do dado no momento da escrita e sua decriptação durante a leitura são automáticos e se utilizam de uma chave simétrica que é gerenciada pelo serviço.
A implementação do TDE no AZURE SQL Database é muito simples e é implementada por default em todas as novas bases de dados que você criar.
Para mudar esta configuração nas bases antigas ou desativar a encriptação em bases novas (o que não me parece boa ideia), acesse o portal do AZURE, localize a base de dados que deseja configurar, role o menu até encontrar o grupo SECURITY e escolha a guia TRANSPARENT DATA ENCRYPTION, marcando o serviço como ON ou OFF.
Entenda que existem duas chaves de encriptação aqui. Uma é a Database Encryption Key (DEK), que efetivamente encripta os dados da base. Com a configuração apresentada acima, significa que ativamos a DEK desta base de dados.
Quando se usa geo-replicação em bases com TDE, por exemplo, a(s) base(s) secundária(s) compartilha(m) a mesma chave de encriptação da base primária, ou seja, a mesma DEK.
Mas existe um mecanismo de proteção desta chave, que é oferecido por um segundo certificado, que chamamos de Protetor do TDE. O protetor atua ao nível de servidor e, por default, a chave criptográfica deste protetor é gerenciada pelo próprio serviço do AZURE SQL Database. Todo ciclo de vida desta chave (criação, prazo de validade e
expiração) é gerenciado automaticamente.
TDE-BYOK
Existe uma outra forma de trabalho, em que o usuário assume o controle do gerenciamento da chave de encriptação do protetor do TDE. Esta alternativa é chamada de BYOK (sigla em inglês para “Bring Your Own Key”).
Para sua implementação, é preciso respeitar 2 principais requisitos:
1. SQL DATABASE precisa necessariamente estar integrado ao AAD.
2. KEY VAULT precisa necessariamente ter a opção SOFT-DELETE ativada (para evitar problemas com chaves apagadas acidentalmente). Esta opção está disponível no momento da criação do cofre. Caso deseje usar um cofre que foi criado sem esta funcionalidade, você pode configurá-lo usando POWERSHELL. Importante saber que,
uma vez ativada, esta mudança é irreversível.
Uma vez resolvidos estes requisitos, basta criar uma chave no KEY VAULT (via portal do AZURE, se preferir) e buscar o servidor SQL no portal do AZURE, já que agora estamos tratando da chave criptográfica do Protetor do TDE.
Na sequência, procure o grupo SECURITY e escolha a guia TRANSPARENT DATA ENCRYPTION novamente. Você verá uma imagem ligeiramente diferente e ali poderá escolher a opção CUSTOMER-MANAGED KEY, informar o nome do Key Vault a ser usado e apontar para chave que havia criado lá. Ao final, basta salvar a nova
configuração.
Esta operação não envolve downtime e não requer nova encriptação de dados. É apenas a troca da chave usada pelo protetor do TDE.
ALWAYS ENCRYPTED
Esta criptografia trata de encriptação de informações sigilosas, como número de documentos, cartões de crédito etc. Por isso é implementada ao nível de coluna.
Desse modo, o mecanismo do SQL DB não tem acesso à chave de encriptação. O dado é encriptado na aplicação, enviado como uma coluna binária e então armazenado como tal. Seu significado é desconhecido a menos que se tenha acesso à chave utilizada.
O resultado aqui é que a coluna só é legível para quem acessar o dado através do driver adequado. Nem mesmo os proprietários do banco terão acesso a esta informação (apenas ao valor encriptado, é claro).
É possível implementar o ALWAYS ENCRYPTED através de dois métodos diferentes:
- Com Chave Determinística: de modo que se possa fazer comparações de igualdade (leia-se: permite usar o campo encriptado na cláusula WHERE)
- Chave aleatória (“randômica”): encripta dados de maneira aleatória, oferecendo maior segurança. Porém, você não vai conseguir usar este campo para fazer comparações, porque o resultado encriptado não é necessariamente sempre o mesmo. Para mais informações, consulte a documentação citada nas LEITURAS SUGERIDAS.
O processo de encriptação usa duas chaves: a chave mestra e a chave de encriptação da coluna. Uma funcionalidade que não é default apesar de ser de extrema importância é armazenar estas chaves no AZURE KEY VAULT, para garantir a maior proteção possível. O roteiro a seguir mostra todas as etapas do processo.
Primeiramente eu criei a tabela desejada, ainda sem encriptação. IMPORTANTE: utilizei o SQL Server Management Studio versão 18.5 (ou SSMS). Versões antigas podem apresentar assistentes e configurações diferentes.
Meu objetivo era proteger os dados da coluna DOCUMENTO, que armazenaria o CPF do usuário. Então o passo seguinte foi procurar a guia SECURITY para o meu banco de dados, cliquei o botão direito e escolhi ALWAYS ENCRYPTED KEYS. A chave mestra foi a primeira a ser criada.
O assistente pediu que informasse o nome da chave mestra, onde ela seria armazenada (escolha sempre AZURE KEY VAULT, caso já tenha contratado o serviço). Então informei minha assinatura dos serviços AZURE, o nome do cofre que desejava usar. Finalmente cliquei em GENERATE KEY e então OK.
Em seguida, repeti o processo para criar uma chave de encriptação de coluna. Comecei clicando botão direito sobre o grupo desejado, informei o nome da nova chave e a chave mestra que iria usar (aquela que acabei de criar na etapa anterior).
Neste ponto, já tinha os elementos para encriptar a coluna desejada. Então localizei a tabela que continha a coluna a ser encriptada, cliquei botão direito outra vez e ativei o assistente ENCRYPT COLUMNS.
O próximo passo foi escolher a coluna a ser encriptada, tipo de encriptação e qual chave de encriptação de coluna deveria ser usada. E então encerrei o processo com o conhecido NEXT-NEXT-FINISH.
A coluna DOCUMENTO está finalmente encriptada. Mas a tabela continua vazia e são necessários cuidados especiais para inserir dados nesta nova coluna encriptada.
A primeira ação necessária é alterar os parâmetros de conexão da sua aplicação e ou IDE para trabalhar com ALWAYS ENCRYPTED. Como comentei anteriormente, é necessário usar driver de conexão que suporte este tipo de criptografia.
Para mostrar como isso funciona, preparei uma simulação diretamente no SSMS. Abri uma nova janela configurando uma nossa sessão: ali mantive o login e senha queestava usando, mas especifiquei o nome do meu banco de dados na aba CONNECTION PROPERTIES e habilitei a opção ENABLE ALWAYS ENCRYPTED na aba ALWAYS ENCRYPTED, como mostra a imagem a seguir.
Por que especifiquei o banco de dados na conexão? Simples. O driver de conexão necessita acesso à chave criptográfica da coluna e, evidentemente, esta chave está configurada apenas nesta base de dados.
Resolvido o primeiro ponto, vamos ao segundo. É necessário criar uma consulta parametrizada para que a variável usada seja devidamente encriptada antes da inserção do registro. Com estes cuidados, eu consigo executar comandos DML usando texto plano (encriptação/decriptação são providenciadas pela própria conexão).
Observe que escrita e leitura funcionaram normalmente, como se vê na figura acima. Só por conferência, abro agora uma conexão normal para ler os dados… e então apenas dados encriptados são apresentados.
Caso deseje dar privilégios para que um usuário ou grupo tenham acesso aos dados encriptados, é preciso especificar estas permissões, como mostra o quadro a seguir.
Máscara de Dados Dinâmica (DDM)
DDM não é propriamente uma encriptação dos dados de uma coluna, mas apenas seu mascaramento enquanto são lidos. Portanto não é um tratamento físico e sim lógico: acrescenta uma determinada máscara aos dados para que eles não sejam inteiramente legíveis.
A máscara é aplicada para exibição dos dados no momento da consulta. E se aplica a todos usuários, exceto aqueles que tenham privilégio especial sobre a tabela envolvida. Esse acesso é controlado atribuindo ou revogando privilégio de UNMASK. Porém este privilégio é atribuído ao nível de base de dados, isto é, autoriza leitura de TODAS as colunas mascaradas existentes no banco.
Por ser uma operação lógica, o tipo de máscara usada pode ser alterado a qualquer momento sem nenhum impacto nos dados. Veja a documentação para mais detalhes sobre os tipos de mascaramento disponíveis.
O código abaixo ilustra a criação de colunas com DDM e atribuição de privilégio de leitura para um usuário comum. IMPORTANTE: como este batch inclui uma inserção de registro com coluna encriptada ALWAYS ON, é necessário estabelecer uma conexão com o SQL Server conforme descrito na seção anterior.
Usuários com perfil de DBONWER herdam o privilégio de controle sobre a máscara e, portanto, lerão todos os dados. Porém o usuário “PeDeChinelo” vai ler dados mascarados, como mostra a imagem a seguir.
Observe neste exemplo que criei estas colunas com DDM na mesma tabela que já possuía uma coluna com ALWAYS ENCRYPTED e dentro de uma base que trabalha com TDE.
Em outras palavras, podemos combinar os diferentes tipos de criptografia dentro do AZURE SQL DATABASE. (A menos, é claro, que se tente criar uma coluna ALWAYS ENCRYPTED e adicionar uma máscara DDM, o que não faz nenhum sentido, visto que o dado já está fisicamente encriptado).
Comentários Finais
Segurança de dados é um tópico de grande importância, especialmente em se tratando de bancos de dados na nuvem.
Como se pode ver nos exemplos apresentados aqui, a implementação dos vários tipos de proteção de dados no AZURE SQL DATABASE é bastante simples e praticamente idêntica ao que se faz em servidores on-premises.
Já a integração com AZURE KEY VAULT apresenta um custo insignificante se comparado ao nível de proteção que oferece, seja para serviços da nuvem e/ou on-premises.
Leituras Sugeridas
1. An overview of Azure SQL Database & SQL Managed Instance security capabilities por MICROSOFT.
2. Transparent data encryption for SQL Database, SQL Managed Instance & Azure Synapse por MICROSOFT
3. Always Encrypted por MICROSOFT.
4. Query columns using Always Encrypted with SQL Server Management Studio por MICROSOFT
5. Dynamic Data Masking por MICROSOFT.