- SQL Server 2008 – Como criptografar seus dados utilizando Transparent Data Encryption (TDE)
- SQL Server 2016 – Como criptografar seus dados utilizando Always Encrypted
- SQL Server 2016 – Mascaramento de dados com o Dynamic Data Masking (DDM)
- Lei Geral de Proteção de Dados Pessoais (LGPDP ou LGPD) aplicada a bancos de dados SQL Server
- SQL Server – Evitando consultas em determinadas colunas com o Column Level Security (CLS)
Fala galera!
Prontos para mais um artigo ?
Introduction
Com o advento do GDPR, a preocupação das empresas com segurança de dados vem crescendo cada vez mais, e uma área que antes era por vezes deixada de lado, está em evidência mais do que nunca agora. Em decorrência disso, os profissionais de TI, em especial os DBAs, vem procurando formas de reduzir os riscos de exposição de dados e uma das formas de se fazer isso, é criptografando os dados para evitar acesso não autorizado por terceiros.
A minha ideia nesse artigo é demonstrar uma solução do SQL Server que permite criptografar os dados, que é o Always Encrypted, disponÃvel a partir do SQL Server 2016 nas edições Express, Standard, Enterprise e Developer (Express e Standard a partir do 2016 SP1).
Não deixe de conferir o meu post SQL Server 2008 – Como criptografar seus dados utilizando Transparent Data Encryption (TDE), outra solução de criptografia de dados do SQL Server.
Para os exemplos abaixo, vou utilizar o seguinte script para geração da base:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 |
IF (OBJECT_ID('dbo.Pessoa') IS NOT NULL) DROP TABLE dbo.Pessoa CREATE TABLE dbo.Pessoa ( [Name] NVARCHAR(101), [BirthDate] DATE, [EmailAddress] NVARCHAR(50), [Phone] NVARCHAR(20) ) INSERT INTO dbo.Pessoa VALUES |
O que é o Always Encrypted
O Always Encrypted é um recurso criado para proteger dados confidenciais, disponÃvel a partir do SQL Server 2016, como números de cartão de crédito ou de identificação nacional (por exemplo, números de previdência social dos EUA), armazenados em bancos de dados do Banco de dados SQL do Azure ou SQL Server. O Always Encrypted permite que os clientes criptografem os dados confidenciais em aplicativos de cliente e nunca revelem as chaves de criptografia para o Mecanismo de Banco de Dados. Como resultado, o Always Encrypted fornece uma separação entre aqueles que possuem os dados (e podem exibi-lo) e aqueles que gerenciam os dados (mas que não devem ter acesso).
Uma das maiores vantagens do Always Encrypted é que apenas os usuários e aplicações que possuem a chave mestra de criptografia tem acesso aos dados originais. Nem mesmo os DBAs e outros usuários sysadmin conseguem visualizar os dados originais. Isso garante uma segurança aos dados e informações num nÃvel raramente visto em outras soluções. Outra grande vantagem dessa solução, é que os dados são criptografados e também os logs, os backups e os dados trafegados pela rede, garantindo total segurança em todos os meios de comunicação, mesmo que alguém intercepte pacotes durante a transmissão dos mesmos. Em vista disso, a perda da chave mestra pode ser fatal para os seus dados, pois a recuperação dos mesmos não é mais possÃvel, uma vez que um backup realizado em um database com Always Encrypted só pode ser restaurado em outra instância caso a chave mestra seja restaurada antes.
O Always Encrypted torna a criptografia quase transparente para os aplicativos. Um driver habilitado para Always Encrypted instalado no computador cliente realiza isso automaticamente criptografando e descriptografando dados confidenciais no aplicativo cliente. O driver criptografa as colunas de dados confidenciais antes de passar os dados para o Mecanismo de Banco de Dadose reconfigura automaticamente as consultas para que a semântica do aplicativo seja preservada. Da mesma forma, o driver descriptografa de modo transparente os dados armazenados em colunas de banco de dados criptografado que estão contidos nos resultados da consulta.
Entretanto, embora esse recurso garanta um excelente nÃvel de segurança, fique atento a possÃveis problemas de performance ao utilizá-lo e aumento do consumo de espaço:
Always Encrypted vs Transparent Data Encryption (TDE)
Logo abaixo, vou listar algumas semelhanças e diferenças entre essas duas soluções de criptografia do SQL Server:
Always Encrypted | Transparent Data Encryption (TDE) |
---|---|
NÃvel de coluna | NÃvel de database |
Criptografia no cliente (utilizando um driver) | Criptografia no servidor (Database Engine) |
Servidor não conhece as chaves de criptografia | Servidor conhece as chaves de criptografia |
Dados na memória são criptografados | Dados na memória são desprotegidos (plain-text) |
Dados na rede são criptografados | Dados na rede são desprotegidos (plain-text) |
Apenas os usuários com acesso à chave podem visualizar os dados originais. Nem mesmo o DBA pode visualizar os dados originais sem a chave. | O DBA pode visualizar os dados originais sem a chave |
Backups e arquivos de log são criptografados | Backups e arquivos de log são criptografados |
Exige alterações na aplicação (podem ser pequenas ou grandes, de acordo com o algoritmo de criptografia escolhido) | Não exige alterações na aplicação |
DisponÃvel a partir do SQL Server 2016 - Todas as edições, até Express (Express e Standard a partir do 2016 SP1) | DisponÃvel a partir do SQL Server 2008 - Apenas Enterprise e Developer |
Criptografia DeterminÃstica ou Aleatória
Ao utilizar o Always Encrypted, você verá que existem 2 formas de criptografar colunas nessa solução:
- DeterminÃstica (Deterministic): A criptografia determinÃstica sempre gera o mesmo valor criptografado para o mesmo texto. Usar a criptografia determinÃstica proporciona lookups, joins, agrupamentos e indexação em colunas criptografadas. No entanto, também pode permitir que usuários não autorizados estimem informações sobre valores criptografados examinando padrões na coluna criptografada, especialmente se houver um pequeno conjunto de valores possÃveis criptografados, como True/False ou região Norte/Sul/Leste/Oeste.
- Aleatória (Randomized): A criptografia aleatória usa um método que criptografa os dados de uma maneira menos previsÃvel, ou seja, para um mesmo texto o valor criptografado é diferente. A criptografia aleatória é mais segura, mas impede o uso de pesquisas, agrupamentos, indexação e joins em colunas criptografadas.
Como instalar e configurar o Always Encrypted no SQL Server
Agora que já expliquei um pouco da teoria do Always Encrypted, vamos partir para a parte prática.
A forma mais prática de se criptografar uma coluna, é utilizando o SQL Server Management Studio (SSMS):
E a alteração de tabelas existentes também pode ser feita utilizando PowerShell:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
Import-Module SqlServer $sqlConnectionString = "Data Source=sqlserver\sql2017;Initial Catalog=AdventureWorksDW;User ID=dirceu.resende;MultipleActiveResultSets=False;Connect Timeout=30;Encrypt=False;TrustServerCertificate=False;Packet Size=4096;Application Name=`"Microsoft SQL Server Management Studio`"" $smoDatabase = Get-SqlDatabase -ConnectionString $sqlConnectionString # If your encryption changes involve keys in Azure Key Vault, uncomment one of the lines below in order to authenticate: # * Prompt for a username and password: #Add-SqlAzureAuthenticationContext -Interactive # * Enter a Client ID, Secret, and Tenant ID: #Add-SqlAzureAuthenticationContext -ClientID '<Client ID>' -Secret '<Secret>' -Tenant '<Tenant ID>' $encryptionChanges = @() # Add changes for table [dbo].[Pessoa] $encryptionChanges += New-SqlColumnEncryptionSettings -ColumnName dbo.Pessoa.Name -EncryptionType Randomized -EncryptionKey "CEK_Auto1" $encryptionChanges += New-SqlColumnEncryptionSettings -ColumnName dbo.Pessoa.BirthDate -EncryptionType Deterministic -EncryptionKey "CEK_Auto1" $encryptionChanges += New-SqlColumnEncryptionSettings -ColumnName dbo.Pessoa.EmailAddress -EncryptionType Randomized -EncryptionKey "CEK_Auto1" $encryptionChanges += New-SqlColumnEncryptionSettings -ColumnName dbo.Pessoa.Phone -EncryptionType Randomized -EncryptionKey "CEK_Auto1" Set-SqlColumnEncryption -ColumnEncryptionSettings $encryptionChanges -InputObject $smoDatabase |
Entretanto, não é possÃvel criptografar colunas de tabelas já existentes utilizando Transact-SQL, apenas realizar a criação de uma nova tabela criptografada (você pode criar uma nova tabela criptografada e migrar os dados da tabela anterior), que teria essa sintaxe:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 |
USE [dirceuresende] GO CREATE COLUMN MASTER KEY [CMK_Auto1] WITH ( KEY_STORE_PROVIDER_NAME = N'MSSQL_CERTIFICATE_STORE', KEY_PATH = N'CurrentUser/my/D8CDCC7BC22069DEC1FCF32A5C349FCD33424FAA' ) GO CREATE COLUMN ENCRYPTION KEY [CEK_Auto1] WITH VALUES ( COLUMN_MASTER_KEY = [CMK_Auto1], ALGORITHM = 'RSA_OAEP', ENCRYPTED_VALUE = 0x016E000001630075007200720065006E00740075007300650072002F006D0079002F006400380063006400630063003700620063003200320030003600390064006500630031006600630066003300320061003500630033003400390066006300640033003300340032003400660061006100435052EEFF25542A375E23CC9E0BE2B79116313A2A14F3F3AE362B4075368EADB9EB3AB7BC19B14972204CD1E092B6DF0AC9C6BB0067F96AF7EED7C6360273B947EDAE5643932262E43D3C412B1F680929C263C9DD1839D86EDEBCCC6F2F307910CBD123ADB761BFD167F44C77BF6355114955DF371332D429A4DD79C9C51E02A781A977987947CAEF8FED3A30B4B3E9C8EE400F2F416289FE76DCC24B7D509D8ABA35C34959678CF31A704CD4E4C5105CA23CA09F4DD05AEABF413113E093FF7F398C859CA90C05F42DA5C43871DD0DDD95C555B524E342E6125DEA069C6ABF80F7A741B1ADCC73408B3A98C08CAEAC9325079F66256AC8835574FA5E38BCD634ED0BC71DE05EF61E1FEB4ACC1E62DEDDFFC5E86D2E6B3CBE1BEE22588FE29BA3AEB94FA46AF77C22AD7421F606836EC4BC1A3353019106E9B55E20A7DB72A06C63ADB4F438C191DCBA891FEF0F874AAF569C42730EF18E7E84754640D0EC37F48BA8E0455569E59F497849F9295962725D71769FE806B15556A7716341B7560B5E28323FB00846D4EEC0DF2C50339693EF29D83667EE88781FEB079460CB6A2FA49CD5418226D8465957DD5B95EECAF12B0AD436B40FE2F70F7E96A506E3ECACC94C4394A6D103532546541950D58D0057185BB024A98204006697BCB30CE8077CD2A39C7BAED5D76391294A35914B132C798173ED5AE4EDC7551D97F7C5B6 ) GO CREATE TABLE [dbo].[Pessoa]( [Name] [NVARCHAR](101) COLLATE Latin1_General_BIN2 ENCRYPTED WITH (COLUMN_ENCRYPTION_KEY = [CEK_Auto1], ENCRYPTION_TYPE = RANDOMIZED, ALGORITHM = 'AEAD_AES_256_CBC_HMAC_SHA_256') NULL, [BirthDate] [DATE] ENCRYPTED WITH (COLUMN_ENCRYPTION_KEY = [CEK_Auto1], ENCRYPTION_TYPE = DETERMINISTIC, ALGORITHM = 'AEAD_AES_256_CBC_HMAC_SHA_256') NULL, [EmailAddress] [NVARCHAR](50) COLLATE Latin1_General_BIN2 ENCRYPTED WITH (COLUMN_ENCRYPTION_KEY = [CEK_Auto1], ENCRYPTION_TYPE = RANDOMIZED, ALGORITHM = 'AEAD_AES_256_CBC_HMAC_SHA_256') NULL, [Phone] [NVARCHAR](20) COLLATE Latin1_General_BIN2 ENCRYPTED WITH (COLUMN_ENCRYPTION_KEY = [CEK_Auto1], ENCRYPTION_TYPE = RANDOMIZED, ALGORITHM = 'AEAD_AES_256_CBC_HMAC_SHA_256') NULL ) GO |
Visualizando os dados do Always Encrypted no SQL Server
Agora que criptografamos as colunas da tabela dbo.Pessoa, vamos tentar visualizar os dados originais, logado com um usuário sysadmin:
Para visualizar novamente os dados originais no SSMS, você precisará informar o parâmetro column encryption setting=enabled na string de conexão:
Após alterar essa configuração, você poderá visualizar os dados originais novamente.
Vale lembrar que o usuário só poderá ver os dados originais se ele tiver as permissões de VIEW ANY COLUMN MASTER KEY DEFINITION e VIEW ANY COLUMN ENCRYPTION KEY DEFINITION ou se você estiver armazenando as Master Encryption Key e Column Encryption Key no servidor de banco (Windows Certification Store) e o certificado está armazenado na sua máquina ou no seu usuário. Caso você queira utilizar uma forma mais segura, opte pelo Azure Key Vault (AKV).
Para auxiliar na configuração do Always Encrypted em suas aplicações, separei mais 2 artigos que podem auxiliar os DEV’s a configurarem esse recurso com o Azure Key Vault (AKV):
- https://docs.microsoft.com/en-us/azure/sql-database/sql-database-always-encrypted-azure-key-vault
- https://blogs.msdn.microsoft.com/sqlsecurity/2015/11/10/using-the-azure-key-vault-key-store-provider-for-always-encrypted/
Como identificar quais colunas estão criptografas com Always Encrypted
Para identificar quais colunas estão criptografadas com Always Encrypted e qual o algoritmo de criptografia utilizado, basta utilizar a consulta abaixo:
1 2 3 4 5 6 7 8 9 10 11 12 |
SELECT DB_NAME() AS [database], t.[name] AS [table], c.[name] AS [column], c.encryption_algorithm_name, c.[encryption_type], c.encryption_type_desc FROM sys.columns c JOIN sys.tables t ON t.[object_id] = c.[object_id] WHERE c.encryption_algorithm_name IS NOT NULL |
Restrições do Always Encrypted
Não há suporte para o Always Encrypted nas colunas com as caracterÃsticas abaixo (por exemplo, a cláusula Encrypted WITH não poderá ser usada em CREATE TABLE/ALTER TABLE de uma coluna se uma das seguintes condições se aplicar à coluna):
- Colunas usando um dos seguintes tipos de dados: xml, timestamp/rowversion, image, ntext, text, sql_variant, hierarchyid, geography, geometry, alias e tipos definidos pelo usuário.
- Colunas FILESTREAM
- Colunas com a propriedade IDENTITY
- Colunas com a propriedade ROWGUIDCOL.
- Colunas de strings (varchar, char, etc.) com agrupamentos não bin2
- Colunas que são chaves para Ãndices não clusterizados usando uma coluna criptografada de forma aleatória como uma coluna de chave (colunas criptografadas de forma determinÃstica são permitidas)
- Colunas que são chaves para Ãndices clusterizados usando uma coluna criptografada de forma aleatória como uma coluna de chave (colunas criptografadas de forma determinÃstica são permitidas)
- Colunas que são chaves para Ãndices de fulltext contendo colunas criptografadas, aleatórias e determinÃsticas
- Colunas referenciadas por colunas computadas (quando a expressão realiza operações sem suporte para o Always Encrypted)
- Conjunto de colunas sparse
- Colunas que são referenciadas por estatÃsticas
- Colunas usando tipo de alias
- Colunas de particionamento
- Colunas com constraint default
- Colunas referenciadas por unique constraints ao usar a criptografia aleatória (há suporte para a criptografia determinÃstica)
- Colunas de chave primária ao usar a criptografia aleatória (há suporte para a criptografia determinÃstica)
- Fazer referência a colunas em restrições de chave estrangeira ao usar a criptografia aleatória, ou ao usar a criptografia determinÃstica, se as colunas referenciadas e de referência usarem algoritmos ou chaves diferentes
- Colunas referenciadas por constraint de check
- Colunas em tabelas que usam Change Data Capture (CDC)
- Colunas de chave primária em tabelas com Change Tracking
- Colunas mascaradas (usando Dynamic Data Masking)
- Colunas em tabelas Stretch Database (Tabelas com colunas criptografadas com o Always Encrypted podem ser habilitadas para Stretch.)
- Colunas em tabelas externas (PolyBase) (observação: há suporte para o uso de tabelas externas e tabelas com colunas criptografadas na mesma consulta)
- Não há suporte para parâmetros com valor de tabela com direcionamento a colunas criptografadas.
As cláusulas a seguir não podem ser usadas para colunas criptografadas:
- FOR XML
- FOR JSON PATH
Os recursos a seguir não funcionam em colunas criptografadas:
- Replicação transacional ou replicação merge
- Consultas distribuÃdas (servidores vinculados)
Dynamic Data Masking
Após demonstrar o uso dessa solução de criptografia, você estar se perguntando: “E o Dynamic Data Masking (DDM)???”. Bom, para começar, o DDM não é uma solução de criptografia de dados e sim uma solução de mascaramento de dados.
Enquanto a criptografia de dados efetivamente impede que os seus dados sejam restaurados (inclusive, a partir de backups) e acessados indevidamente, o mascaramento de dados com o Dynamic Data Masking apenas restringe o conteúdo que é mostrado ao final de um comando de SELECT, ou seja, caso você tenha acesso a um arquivo de backup, você pode restaurá-lo em uma instância onde você seja sysadmin e terá acesso livre aos dados antes mascarados.
Para saber mais sobre o Dynamic Data Masking, veja o artigo SQL Server 2016 – Mascaramento de dados com o Dynamic Data Masking (DDM), onde demonstro como utilizá-lo, restrições e até mesmo como “quebrar” o mascaramento e acessar os dados originais (mesmo sem ter permissão para isso).
Bom pessoal, espero que tenham gostado desse artigo e agora comecem a proteger melhor seus dados!
Grande abraço e até a próxima!
Olá Resende!
Primeiramente parabéns pelos seus conteúdos, sua didática é extremamente sensacional!
Meus testes não foram realizados com sucesso na tentativa de criptografar campos com strings utilizando os métodos com senhas e/ou certificado usando os algoritimos permitidos como o AES_256;
Ex.:
CREATE SYMMETRIC KEY Key_BAN
WITH ALGORITHM = AES_256
ENCRYPTION BY CERTIFICATE Cert_BAN;
As restrições de criptografia descritas em seu post se estendem para as demais formas de criptografia, ou seja, para a criptografia a nÃvel de coluna utilizando senha e/ou certificado?