Seções iMasters
SQL Server

Criptografia de dados no SQL Server – Simétrica e Assimétrica

Olá, caros leitores! Hoje abordaremos um assunto delicado, que é a criptografia de dados no SQL Server.

O SQL Server 2005/2008 suporta nativamente a maioria dos métodos de criptografia, como criptografia simétrica, criptografia assimétrica, uso de certificados e TDE –  Criptografia Transparente de Dados.

O SQL Server criptografa os dados usando um sistema de criptografia hierárquica, significa que cada camada criptografa a camada mais abaixo, e infraestrutura de gerenciamento de chaves.

Para ver o gráfico que foi fornecido pela Technet para ilustrar a Hierarquia de criptografia, clique aqui.

Vejamos em detalhes os métodos de criptografia simétrica e criptografia assimétrica.

Criptografia simétrica

A criptografia simétrica é o método mais antigo e conhecido na computação, utiliza a mesma chave para criptografar e para descriptografar os dados contidos em nosso banco de dados.

É o método mais recomendado para rotinas no banco de dados, e consegue unir uma boa performance na recuperação de dados e uma segurança adequada para a maioria dos casos.

Para criar uma chave simétrica no SQL Server 2005/2008, use o código abaixo:

CREATE SYMMETRIC KEY NomeDaChave [ AUTHORIZATION nome_usuario] WITH ALGORITHM = AlgoritimoDeCriptografia
ENCRYPTION BY {CERTIFICATE NomeCertificado | PASSWORD = SenhaForte |  SYMMETRIC KEY  NomeDaChave | ASYMMETRIC KEY NomeDaChave}

O comando acima cria uma nova chave simétrica no SQL Server, vamos entender melhor o que cada argumento faz.

NomeDaChave

Nome da chave simétrica no banco de dados, esse nome é exclusivo, você pode criar uma chave temporária usando o prefixo #NomeDaChave.

AUTHORIZATION nome_usuario

Especifica o nome do usuário do banco de dados ou função de aplicativo que possuirá essa chave, esse argumento é opcional.

ALGORITHM = AlgoritimoDeCriptografia
Você deve informar ao comando CREATE qual algoritmo de criptografia ele deve usar, existem as seguintes opções:  DES | TRIPLE_DES | TRIPLE_DES_3KEY | RC2 | RC4 | RC4_128 | DESX | AES_128 | AES_192 | AES_256

Existem duas observações importantes no MSDN que devem ser levadas em consideração para a escolha do algoritmo:

Reprovação do algoritmo RC4. 
O uso repetido do mesmo RC4 ou RC4_128 KEY_GUID em blocos de dados diferentes resultam na mesma chave RC4 porque o SQL Server não fornece um salt automaticamente. O uso da mesma chave RC4 repetidamente é um erro bem conhecido que resulta em criptografia muito fraca. Portanto, preterimos as palavras-chave RC4 e RC4_128. Esse recurso será removido em uma versão futura do Microsoft SQL Server. Não utilize esse recurso em desenvolvimentos novos e modifique, assim que possível, os aplicativos que atualmente o utilizam. 

Esclarecimento em relação aos algoritmos DES:

  • O DESX foi nomeado incorretamente. As chaves simétricas criadas com ALGORITHM = DESX na verdade usam a cifra TRIPLE DES com uma chave de 192 bits. O algoritmo DESX não é fornecido. Esse recurso será removido em uma versão futura do Microsoft SQL Server. Evite usar esse recurso em desenvolvimentos novos e planeje modificar os aplicativos que atualmente o utilizam.
  • As chaves simétricas criadas com ALGORITHM = TRIPLE_DES_3KEY usam TRIPLE DES com uma chave de 192 bits.
  • As chaves simétricas criadas com ALGORITHM = TRIPLE_DES usam TRIPLE DES com uma chave de 128 bits.

Fonte: MSDN

ENCRYPTION BY {CERTIFICATE | PASSWORD |  SYMMETRIC KEY | ASYMMETRIC KEY}
Quando uma chave simétrica é criada, ela deve ser criptografada usando um dos métodos citados na sintaxe, veja a diferença de cada um.

CERTIFICATE

Especifica o nome do certificado que será usado para criptografar a chave simétrica. O certificado já deve existir no banco de dados.

PASSWORD

Especifica uma senha para criptografar a chave, essa senha deve ser compatível com as diretivas de senha do Windows. Use sempre uma senha forte para criptografar uma chave simétrica.

SYMMETRIC KEY 

Você deve especificar o nome de uma chave simétrica já existente no banco de dados, essa chave será usada para criptografar a chave que está sendo criada.

ASYMMETRIC KEY

Você deve especificar o nome de uma chave simétrica já existente no banco de dados, essa chave será usada para criptografar a chave que está sendo criada.

Criptografia simétrica na prática

1 - Crie um novo banco de dados chamado CriptografiaNoSqlServer, fique à vontade para escolher o nome que quiser.

CREATE DATABASE [CriptografiaNoSqlServer]

2 – Vamos criar uma nova tabela chamada CadastroDePessoas, segue o código:

CREATE TABLE [dbo].[CadastroDePessoas](
[Codigo] [int] IDENTITY(1,1) NOT NULL,
[NomeCompleto] [nvarchar](50) NOT NULL,
[RG] [varbinary](MAX) NOT NULL,
[CPF] [varbinary](MAX) NOT NULL,
[Login] [varbinary](MAX) NOT NULL,
[Senha] [nvarchar](50) NOT NULL,
[Ativo] [bit] NOT NULL,
CONSTRAINT [PK_CadastroDePessoas] PRIMARY KEY CLUSTERED
(
[Codigo] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
GO
ALTER TABLE [dbo].[CadastroDePessoas] ADD CONSTRAINT [DF_CadastroDePessoas_Ativo] DEFAULT ((0)) FOR [Ativo]
GO

Veja que nossa tabela tem os campos RG, CPF e Login como varbinary, isso é feito para guardar os dados criptografados no formato binário.

Para criar uma chave simétrica, você deve escolher como ela será criptografada, o SQL Server trabalha com hierarquia de criptografia, então a chave simétrica também é criptografada.

Criando uma nova chave simétrica chamada ChaveSimetrica01 e usando uma senha para criptografá-la:

CREATE SYMMETRIC KEY ChaveSimetrica01 WITH ALGORITHM = TRIPLE_DES_3KEY ENCRYPTION BY PASSWORD = N'xF0F1F2'

Para saber se sua chave foi criada com sucesso, use o seguinte comando:

SELECT * FROM sys.symmetric_keys

3 – Agora vamos incluir uma pessoa em nossa tabela.

/**
ABRIMOS A CHAVE SIMÉTRICA ANTES DE USAR
*/
OPEN SYMMETRIC KEY ChaveSimetrica01 DECRYPTION BY PASSWORD = N'xF0F1F2';
/*
INCLUIMOS OS DADOS NA TABELA
*/
INSERT INTO [CadastroDePessoas]([NomeCompleto], [RG], [CPF], [Login], [Senha], [Ativo])
VALUES('Diogo Luiz',
EncryptByKey(Key_GUID('ChaveSimetrica01'), CONVERT(VARBINARY, N'00.000.000-0')) ,
EncryptByKey(Key_GUID('ChaveSimetrica01'), CONVERT(VARBINARY, N'000.000.000-00')) ,
EncryptByKey(Key_GUID('ChaveSimetrica01'), CONVERT(VARBINARY, N'diogoluiz')) ,
N'40bd001563085fc35165329ea1ff5c5ecbdbbeef', 1);

Agora que incluímos uma pessoa, vamos ver como os campos que foram criptografados ficaram.

SELECT RG, CPF, [Login] FROM dbo.CadastroDePessoas

Veja que usamos dois comandos na inclusão de dados, o comando EncryptByKey trabalha juntamente com a função Key_GUID.

A função EncryptByKey é responsável por criptografar os dados inseridos e para fazer isso ela pede como primeiro parâmetro uma chave simétrica. Para selecionar a chave, usamos Key_GUID(‘NomeDaChave‘), então passamos o texto que será encriptado. O texto que será encriptado pode ser dos seguintes tipos: nvarchar, char, varchar, binary, varbinary  e nchar.

Existem mais parâmetros que podem ser usados em EncryptByKey, se quiser saber mais veja a documentação no MSDN.

4 – Recuperando os dados.

Para que possamos usar dados da nossa tabela, precisamos descriptografar as colunas. Para fazer isso, primeiro usamos OPEN SYMMETRIC KEY  para abrir nossa chave simétrica e a função DecryptByKey descriptografa a coluna usando essa chave, veja um exemplo.

OPEN SYMMETRIC KEY ChaveSimetrica01 DECRYPTION BY PASSWORD = N'xF0F1F2';
GO
SELECT CONVERT(VARCHAR, DECRYPTBYKEY(RG)) AS RG,
CONVERT(VARCHAR, DECRYPTBYKEY(CPF)) AS CPF,
CONVERT(VARCHAR, DECRYPTBYKEY([Login])) AS [Login] FROM dbo.CadastroDePessoas

Criptografia assimétrica

O método de criptografia assimétrica ou criptografia de chave pública trabalha de forma bem mais segura que a criptografia simétrica, mas perde em desempenho. O método de chave pública utiliza um par de chaves, uma chave para criptografar (chave pública) e outra para descriptografar (chave privada), além de utilizar algoritmos bem mais
chegando a 2048 bits.

A criptografia assimétrica é indicada na proteção de dados muito sensíveis como números de cartão de crédito, documentos confidenciais etc…

A maneira usada para criar e utilizar chaves assimétricas é muito semelhante a maneira já apresentada na criação de chaves simétricas.

Vamos criar uma nova chave assimétrica:

CREATE ASYMMETRIC KEY NomeDaChave [ AUTHORIZATION nome_usuario
WITH ALGORITHM = AlgoritimoDeCriptografia ENCRYPTION BY PASSWORD = SenhaForte

NomeDaChave

Nome da chave assimétrica no banco de dados, esse nome é exclusivo, você pode criar uma chave temporária  usando o prefixo #NomeDaChave.

AUTHORIZATION nome_usuario

Especifica o nome do usuário do banco de dados ou função de aplicativo que possuirá essa chave, esse argumento é opcional.

ALGORITHM = AlgoritimoDeCriptografia
Você deve informar ao comando CREATE qual algoritmo de criptografia ele deve usar, existem as seguintes opções:  { RSA_512 | RSA_1024 | RSA_2048 }

PASSWORD = ‘SenhaForte

Especifica uma senha para criptografar a chave particular, essa senha deve ser compatível com as diretivas de senha do Windows.
Caso você omita esse parâmetro, o SQL Server vai usar a chave mestra para criptografar a chave particular.

Criptografia assimétrica na prática

1 - Criando uma chave assimétrica.

CREATE ASYMMETRIC KEY ChaveAssimetrica001
WITH ALGORITHM = RSA_2048
ENCRYPTION BY PASSWORD = N'xF0F1F2';
GO

Para verificar se a chave foi criada corretamente, use:

SELECT * FROM sys.asymmetric_keys

Agora incluiremos uma nova pessoa, usando a mesma tabela gerada no exemplo anterior.

INSERT INTO [CadastroDePessoas]([NomeCompleto], [RG], [CPF], [Login], [Senha], [Ativo])
VALUES('Fabiano Costa',
EncryptByAsymKey(AsymKey_ID('ChaveAssimetrica001'), CONVERT(VARBINARY, '11.111.111-1')) ,
EncryptByAsymKey(AsymKey_ID('ChaveAssimetrica001'), CONVERT(VARBINARY, '111.111.111-11')) ,
EncryptByAsymKey(AsymKey_ID('ChaveAssimetrica001'), CONVERT(VARBINARY, 'fabiano')) ,
'40bd001563085fc35165329ea1ff5c5ecbdbbeef', 1);

Veja que não é preciso abrir a chave assimétrica antes de usá-la.

2 – Recuperando os dados.

SELECT CONVERT(VARCHAR, DecryptByAsymKey(AsymKey_ID('ChaveAssimetrica001'), RG, N'xF0F1F2')) AS RG,
CONVERT(VARCHAR, DecryptByAsymKey(AsymKey_ID('ChaveAssimetrica001'), CPF, N'xF0F1F2')) AS CPF,
CONVERT(VARCHAR, DecryptByAsymKey(AsymKey_ID('ChaveAssimetrica001'), [Login], N'xF0F1F2')) AS [Login]
FROM dbo.CadastroDePessoas WHERE NomeCompleto = N'Fabiano Costa'

Para descriptografar as informações, usamos a função DecryptByAsymKey junto com AsymKey_ID.

A função DecryptByAsymKey utiliza três parâmetros no exemplo:

  • O primeiro deve ser o ID da chave assimétrica no banco de dados e para selecionar esse ID usamos a função AsymKey_ID(‘NomeDaChave’);
  • O segundo parâmetro deve ser o texto ou  campo da tabela;
  • O terceiro parâmetro é a senha da chave assimétrica. Caso você omita esse parâmetro, o SQL Server vai usar a chave mestra do banco para descriptografar a chave particular.

Agora que já conhecemos o básico sobre criptografia e como usá-la diretamente no SQL Server, podemos criar STORED PROCEDURES e VIEWS para criptografar e descriptografar os dados automaticamente. Esse recurso é muito valioso e devemos usá-lo sempre que existirem dados sigilosos em nosso banco de dados.

Por enquanto é só. Até a próxima!

Comente também

10 Comentários

Daniel Antoniassi

Caro Diogo, adorei seu artigo e tudo funcionou perfeitamente.

Então resolvi criar uma procedure para fazer a inserção encriptada, mas da erro de conversão dos dados para varbinary, abaixo o que estou fazendo, existe alguma limitaçào?

CREATE PROCEDURE SP_INSERT_CRIPTO
@NomeCompleto nvarchar(50),
@RG varbinary(MAX),
@CPF varbinary(MAX),
@Login varbinary(MAX),
@Senha nvarchar(50),
@Ativo bit
AS
BEGIN
OPEN SYMMETRIC KEY ChaveSimetrica01 DECRYPTION BY PASSWORD = ‘xF0F1F2D1D2′;
INSERT INTO CadastroDePessoas (NomeCompleto, RG, CPF, Login, Senha, Ativo)
Values (
@NomeCompleto,
EncryptByKey(Key_GUID(‘ChaveSimetrica01′), CONVERT(VARBINARY, @RG)),
EncryptByKey(Key_GUID(‘ChaveSimetrica01′), CONVERT(VARBINARY, @CPF)),
EncryptByKey(Key_GUID(‘ChaveSimetrica01′), CONVERT(VARBINARY, @Login)),
@Senha,
@Ativo
)
CLOSE SYMMETRIC KEY ChaveSimetrica01
END

Um abraço!

    Diogo Luiz Corrêa Ponce

    Olá Daniel Antoniassi.
    Acredito que o erro esteja na passagem de parâmetros, tente usar o seguinte.

    @NomeCompleto nvarchar(50),
    @RG nvarchar(20),
    @CPFnvarchar(15),
    @Login nvarchar(50),
    @Senha nvarchar(50),
    @Ativo bit

    O que está acontecendo é que ao passar uma string para o parâmetro que é do tipo varbinary gera um erro de conversão, vc tem que passar os parâmetros no formato nvarchar e fazer a conversão para varbinary no momento da inclusão.

    Espero ter ajudado.
    Diogo Luiz.

Daniel Antoniassi

Diogo, isso mesmo, agora esta rodando perfeitamente.

Um pergunta importante, como faço pra trazer um registro utilizando o where? o dado dever encriptado antes?

Um abraço e parabéns!

    Diogo Luiz Corrêa Ponce

    Fala Daniel blz?
    Para adicionar um where vc deve descriptografar os dados antes e comprar com o valor que vc quer.

    Ex: …. WHERE CONVERT(VARCHAR, DecryptByAsymKey(AsymKey_ID(‘ChaveAssimetrica001′), [RG], N’xF0F1F2′)) = ’00.000.000-0′

    Mas não aconselho fazer isso por um questão de desempenho, entendeu?
    Obrigado por ler e se gostou clica no +1 ;-)

    Abraços.

      Frederic

      Diogo, parabéns pelo artigo, muito bom!

      Mas, criptografar o conteudo pelo qual deseja buscar na clausula where, é melhor do que descriptografar o campo da busca. Evita problemas de performance e de segurança.
      exemplo.
      where RG = EncryptByAsymKey(AsymKey_ID(‘ChaveAssimetrica001′), CONVERT(VARBINARY, ’00.000.000-0′))

Daniel Antoniassi

Última dúvida, e que faltou na Criptografia simétrica, como retorno um dado com o Where?

Emilianni

Parabéns por esse artigo, muito bom mesmo! Pra te dizer a verdade, foi um dos melhores artigos que eu ja encontrei, com exemplos claros, para iniciantes como eu. Parabéns mais uma vez!

Augusto

Oi Diogo, parabéns pelo artigo! São pouquíssimas as pessoas que explicam assim!

Quanto à pergunta do Daniel, respondeste que não “não aconselho fazer isso por um questão de desempenho”. Cara, então qual é a melhor prática?

Saúde e prosperidade e parabens mais uma vez

Gabriel

Primeiramente, Excelente Artigo!

Gostaria de saber como faço para excluir uma chave assimetrica ou até mesmo modificar seu nome caso eu tenha passado algum parametro errado.

Lander Saavedra

gostei da tua tecnica de desenvolvimento…tem algum blog ou canal onde possa te seguir..sempre estou com duvidas referente a criptografia mas quando tem transferência entre internet e intranet na construção de objetos

Qual a sua opinião?