SQL Server – Criptografando senhas com as funções de criptografia simétrica ENCRYPTBYPASSPHRASE e DECRYPTBYPASSPHRASE

Visualizações: 871
Tempo de Leitura: 8 minutos

Fala galera!!
Nesse artigo, eu gostaria de compartilhar com vocês uma solução bem interessante para proteger e criptografar senhas no SQL Server e que possuem possibilidade de recuperação da senha original (desde que você saiba o salt utilizado), que são as funções ENCRYPTBYPASSPHRASE e DECRYPTBYPASSPHRASE, disponíveis desde o SQL Server 2008.

Você gosta de estudar sobre segurança de senhas e criptografias? Veja outros artigos sobre esse assunto:

Um resumo sobre segurança de senhas

Quando se fala em segurança de senhas, precisamos ter em mente que TODO algoritmo que permite a recuperação da string original não é a opção mais segura possível, uma vez que esses métodos geralmente são mais fáceis de serem quebrados que utilizando algoritmos baseados em HASH. Para melhorar o seu entendimento, vou criar um resumo dos 5 tipos básicos de segurança de senha que podemos encontrar, em ordem de menos seguro para o mais seguro.

1) Nenhuma

O modo mais inseguro possível, onde a senha é armazenada sem qualquer criptografia e qualquer pessoa que tenha acesso ao banco/arquivo pode visualizar a senha original.

2) Conversão

Método que adiciona um grau de segurança na senha ao converter os caracteres originais por outros caracteres de acordo com o algoritmo utilizado e essa técnica tem as seguintes características:

  • Um dos algoritmos mais conhecidos que utilizam essa técnica é o Base64
  • O tamanho da string convertida é diferente do tamanho da string original
  • Uma senha ao ser convertida, sempre irá retornar o mesmo resultado
  • Padrões de conversão dos algoritmos são fáceis de serem identificados visualmente, o que facilita identificar qual o algoritmo utilizado

Exemplo:

3) Conversão customizada

Método que adiciona mais um grau de segurança no método anterior ao aplicar embaralhamentos personalizados em cima de algoritmos já conhecidos de conversão, como por exemplo, criar um looping que itere N vezes aplicando a conversão do Base64 várias vezes e aplicando uma função como REVERSE em cada iteração.

Essa técnica não é a mais segura do mundo, mas com certeza, já dificulta um pouco o trabalho de alguém que tente quebrar a segurança de uma senha sua.

Algumas características desse método:

  • Utiliza os algoritmos de conversão e também funções de string
  • O tamanho da string convertida é diferente do tamanho da string original e do algoritmo de conversão original
  • Uma senha ao ser convertida, sempre irá retornar o mesmo resultado
  • Padrões de conversão dos algoritmos não são fáceis de serem identificados visualmente (e podem confundir quem está tentando quebrar o código)

Exemplo:

4) Algoritmos de criptografia simétrica

Algoritmos de chave simétrica são algoritmos para criptografia que usam a mesma chave criptográfica para encriptação de texto puro e decriptação de texto cifrado. A chave, na prática, representa um segredo compartilhado entre duas ou mais partes que pode ser usado para manter uma ligação de informação privada. Este requisito de que ambas as partes possuam acesso à mesma chave secreta é uma das principais desvantagens da criptografia de chave simétrica, em comparação com a criptografia de chave pública (também conhecida como criptografia de chave assimétrica), pois utilizam duas chaves (pública e privada).

Algumas características desse método:

  • Algoritmos mais conhecidos: AES, Twofish, Serpent, Blowfish, CAST5, RC4, 3DES (baseado no DES), IDEA
  • O tamanho da string criptografada é diferente do tamanho da string original (mas é sempre o mesmo tamanho, de acordo com o algoritmo utilizado)
  • A senha só pode ser recuperada caso você saiba a chave privada (Salt)
  • Uma senha ao ser criptografada, irá retornar resultados diferentes a cada execução
  • Difícil identificar qual o algoritmo utilizando analisando apenas o hash

Exemplo:

5) Algoritmos de HASH

Uma senha criptografada com alguma função hash é praticamente impossível de conseguir recuperar o valor original e por isso, podemos dizer que são unidirecionais. Nesse tipo de algoritmo, não é possível recuperar a senha original e a validação da sua identidade se faz por comparações entre o hash criptografado e um novo hash criptografado, gerado em tempo real, a partir da senha que está sendo testada.

Embora seja extremamente seguro, existe a remota possibilidade de 2 senhas diferentes produzirem o mesmo hash (chamado de colisão). Quanto maior a complexidade e segurança do algoritmo utilizado, menor a probabilidade dessa situação ocorrer e também maior é o tempo necessário para criptografar a mensagem e o tamanho do hash gerado. Vale lembrar que esse método também é passível de ataques de força bruta (assim como todos os anteriores).

Algumas características desse método:

  • Algoritmos mais conhecidos: MD4, MD5, SHA-1, SHA-2 (SHA-224, SHA-256, SHA-384, SHA-512, SHA-512/224, SHA-512/256), SHA-3 (Keccak), HMAC
  • O tamanho da string criptografada é diferente do tamanho da string original (mas é sempre o mesmo tamanho, de acordo com o algoritmo utilizado)
  • A senha NÃO pode ser recuperada
  • Uma senha ao ser criptografada, irá retornar sempre o mesmo hash
  • Difícil identificar qual o algoritmo utilizando analisando apenas o hash

Exemplo:

Utilizando as funções ENCRYPTBYPASSPHRASE e DECRYPTBYPASSPHRASE

Agora que fiz um breve resumo sobre segurança de senhas, vamos falar sobre como aplicar isso no SQL Server:

Então só estava faltando demonstrar o método 4 (Algoritmos de criptografia simétrica) aqui no blog. E é por isso que estamos analisando as funções ENCRYPTBYPASSPHRASE e DECRYPTBYPASSPHRASE, que permitem criptografar e descriptografar os dados utilizando uma chave privada (salt) e o algoritmo TRIPLE DES (3DES).

Além dessas funções, você também pode utilizar as ENCRYPTBYASYMKEY, ENCRYPTBYCERT e ENCRYPTBYKEY, mas essas funções são baseadas em certificados e chaves simétricas que precisam ser instalados no servidor para sua utilização.

O uso dessas funções é bem simples e prático:

Resultado:

Tenha apenas atenção quanto ao NVARCHAR. Chave, Mensagem e o formato de retorno tem que ser do mesmo tipo: ou tudo é VARCHAR ou NVARCHAR. Não pode misturar, senão não vai conseguir utilizar essas funções:

SQL 2017+ e Retrocompatibilidade

Disponível desde o SQL Server 2008, as funções ENCRYPTBYPASSPHRASE e DECRYPTBYPASSPHRASE são ótimas soluções simples e fáceis de implementar para melhorar a segurança do armazenamento de senhas e informações sensíveis e elas utilizam internamente, o algoritmo SHA1 para gerar o hash da senha e o 3DES-128 para a criptografia, o que já é uma boa proteção. Na versão 2017 em diante, a Microsoft alterou o código dessas funções para aumentar a segurança, e agora elas utilizam o SHA256 para o hash da senha e o AES-256 para criptografia.

Embora seja um ponto positivo do ponto de vista de segurança das senhas, isso acabou gerando um problema para quem tem as versões antigas do SQL Server e interage com as versões mais novas, que eu vou demonstrar agora.

No SQL 2008, vou gerar um hash para a senha “Dirceu Resende”:

Com o hash gerado “0x01000000940908D92A0826928234D7DD6E3FA27AF5D818FC7654AE39AC090D30DFE5C43C” vou tentar recuperar a mensagem original num SQL Server 2017:

Bom, tudo certo! Maravilha! Pelo visto, a função do SQL Server 2017 consegue “ler” o formato novo e o antigo. Agora vamos fazer o inverso: Vou gerar uma hash no SQL Server 2017:

Nossa, que hash grande.. Vou utilizar a hash “0x02000000F955D4A111500CD5F9287228B3FC927FB7640202F2EC85F6BBA2074CD2434F39FE98CFFAD46718119ABC20AFAE058E2B” para recuperar a senha original do SQL Server 2008:

Vixi.. Retornou NULL! E agora?? Bom, não tem retrocompatibilidade.. E o SQL Server 2008 já não é mais suportado pela Microsoft e provavelmente, não terá um update para incluir isso. Tem solução??

Mas é claro que SIM! E o responsável por isso é o nosso poderoso SQLCLR! Utilizando uma função escrita em C#, podemos disponibilizar uma nova função no SQL Server 2008 que consiga recuperar a senha tanto das versões novas quanto das antigas:

A Hash gerada no próprio SQL Server 2008 também é compatível com essa função:

Resultado:

Quer criar esse SQLCLR no seu ambiente? Já aviso que terá que criar o assembly como UNSAFE (Unrestricted), devido ao uso da biblioteca System.Security.Cryptography.Aes, pois o HPA (atributo de proteção de host) “MayLeakOnAbortnão são permitidos no modo Safe ou External Access.

Dado o aviso, vamos à criação do assembly e da função fncDecryptByPassphrase:

Código-fonte da função caso você mesmo queira compilar e fazer o deploy do projeto:

Bom pessoal, espero que vocês tenham gostado desse post bem técnico e complicado.. rs
Um grande abraço e até o próximo artigo!

Referências: