Segurança e Criptografia de senhas – C#

Recentemente eu acompanhei o um tópico na lista de discussão .Net Br chamado Criptografia Reversível, onde o autor do tópico perguntou sobre maneiras de criptografar as senhas, etc. Eu estou longe de ser um especialista em criptografia, mas me assustei com as respostas sugerindo a utilização de MD5 ou até mesmo criar um algorítimo de inversão da string contendo a senha. Em nenhum momento foi sugerido a utilização de salt, foi defendido que não era necessário implementar uma suposta complexidade no código para que pudesse garantir um mínimo de segurança.
Um comentário bem coerente (citado abaixo) foi rebatido dando a entender que não adianta utilizar técnicas de criptografias mais modernas, pois o algorítimo seguro de hoje é o fraco de amanhã.

NÃO, NUNCA e JAMAIS.

MD5 NÃO é segura para absolutamente nada faz mais de uma década.
NUNCA use MD5 pois existem algorítmos de hashing que são realmente segundo.
JAMAIS sugira para alguém usar MD5, pois é uma ótima forma de garantir um sistema inseguro.

Só fiquei um pouco assustado com a postura das pessoas quanto a este assunto e resolvi escrever um pouco sobre o assunto. Repito novamente, não sou especialista no assunto, mas procuro estudar um pouco sobre o assunto, até porque, todos os desenvolvedores provavelmente deparar-se-ão com uma situação dessas um dia…

O que é Password Hashing e porque utilizá-lo?

Supondo que você está criando um sistema qualquer, onde por algum motivo você deverá gravar algum tipo de informação sensível, como por exemplo uma senha. Quando vamos salvar alguma informação em nosso bando de dados, xml, .ini, etc, nós simplesmente pegamos a informação e a gravamos da maneira que ela estava em sua forma original. O problema de fazer isso com uma senha é que ela estará extremamente vulnerável para qualquer pessoa que tenha acesso ao banco (seja um desenvolvedor ou alguém que invadiu o seu servidor), qualquer pessoa que intercepte a requisição, etc. Isso faz com que o que está sendo protegido com senha, não necessariamente estará protegido.

Para isso, é importante utilizar Password Hashing, que nada mais é do que um algorítimo que dada uma entrada qualquer, será devolvida uma quantidade fixa de bits. Sendo assim, no lugar de salvar em seu banco uma senha como “1234”, você estaria salvando um hash, como “a6es2352sdgOPccw13” (conteúdo completamente aleatório apenas para exemplificar). A vantagem disso, é que para um leigo, esse conteúdo não é de fácil compreensão, fazendo com que a sua senha agora tenha uma segurança a mais. Para isso, você poderia utilizar uma série de algorítimos conhecidos (note que nesta lista não estou falando sobre a segurança deles)

  • SHA256
  • SHA512
  • RipeMD
  • SHA3
  • WHIRLPOOL
  • MD5
  • SHA1

Como mostrado na lista acima, temos diversos algorítimos para isso, mas qual devo utilizar? Sinceramente eu não sou um expert no assunto, mas você consegue obter muitas respostas pelo google: why not use md5 for passwords, why not use sha1 for passwords, how sha256 algorithm works.
Para se ter uma ideia da facilidade de quebrar hashes, de uma olhada no site crackstation.net. Na página inicial deles, você pode inserir um hash que quase instantaneamente eles quebram para você. Mas por que? É tão fácil quebrar esses hashes? Por que devo utilizar hash então?

Utilizar hash é seguro?

Sim, é seguro, mas nem tanto. É possível quebrá-lo de diversas maneiras, utilizando ataques de força bruta ou dicionário. Imagine um banco de dados com vários GBs de hashes possíveis. Utilizando um desses, fica fácil quebrar de forma parcial e/ou integral uma senha. Uma maneira de dificultar, é a utilização de SALT. Salt nada mais é do que adicionar à senha informada um outro hash de forma aleatória, e a partir da junção da senha + salt, gerar um hash utilizando um algorítimo mais seguro, como o SHA512.

hash("hello") = 2cf24dba5fb0a30e26e83b2ac5b9e29e1b161e5c1fa7425e73043362938b9824
hash("hello" + "QxLUF1bgIAdeQX") = 9e209040c863f84a31e719795b2577523954739fe5ed3b58a75cff2127075ed1
hash("hello" + "bv5PehSMfV11Cd") = d1d3ec2e6f20fd420d50e2642992841d8338a314b8ea157c9e18477aaef226ab
hash("hello" + "YYLmfY6IehjZMQ") = a49670c3c18b9e079b9cfaf51634f563dc8ae3070db2c4a8544305df1b60f007

O exemplo acima foi retirado do já citado crackstation.net.
Observe que ao combinarmos um hash à senha para depois gerarmos o nosso hash, modificamos complemente o resultado do hash final, dificultando bastante a vida de quem quiser quebrar a sua senha.
Observe que para que um salt tenha alguma utilidade, é preciso que você tome alguns cuidados, como NUNCA UTILIZAR UM SALT REPETIDO.

Bom, esses foram os meus 2 cents sobre o assunto. Não vou postar implementações, nem nada. Talvez em um outro post.
Abraço 😉

Anúncios

Deixe um comentário

Preencha os seus dados abaixo ou clique em um ícone para log in:

Logotipo do WordPress.com

Você está comentando utilizando sua conta WordPress.com. Sair / Alterar )

Imagem do Twitter

Você está comentando utilizando sua conta Twitter. Sair / Alterar )

Foto do Facebook

Você está comentando utilizando sua conta Facebook. Sair / Alterar )

Foto do Google+

Você está comentando utilizando sua conta Google+. Sair / Alterar )

Conectando a %s