7 de fev de 2015

Qual criptografia utilizar para armazenar senhas?



Ao gerenciar um sistema, muitas vezes precisamos armazenar senhas de usuários no Banco de Dados. Alguns administradores não tomam as devidas precauções ao armazenar esse tipo de informação, e no caso de uma invasão, acaba expondo esses dados extremamente sensíveis. É necessário então, escolher um bom algoritmo de criptografia para prevenir que, no caso de uma invasão, os dados dos usuários não sejam expostos.


NUNCA ARMAZENE SENHAS SEM CRIPTOGRAFIA

Por mais que isso seja óbvio para muitos, acredite, ainda existem administradores que guardam as senhas de seus usuários em texto puro. Nunca faça isso pois caso seu sistema seja invadido ou mesmo esteja vulnerável a falhas como SQL Injection por exemplo, o atacante conseguirá acesso a essas informações críticas.

Alguns administradores são ainda mais irresponsáveis e enviam a senha por email quando você clica no "Esqueci minha senha". Nunca faça isso. Se a senha estiver criptografada, a maneira correta de se fazer é enviar um formulário para redefinição de senha.


NUNCA CRIE SUA PRÓPRIA CRIPTOGRAFIA

A não ser que você seja um criptógrafo, criar sua própria criptografia não é uma boa ideia. Existem profissionais muito bons nessa área, que trabalharam muito para criar cifras criptográficas seguras e algumas dessas cifras como a MD4 possuem fraquezas críticas. Se empresas especializadas em criptografia como a RSA Data Security, Inc já criaram algoritmos de hash com vulnerabilidades, imagine alguém que nunca estudou (ou estudou pouco) sobre criptografia.

Portanto, a menos que você tenha estudado muito, não pense que uma criptografia criada por você será boa. Não adianta pensar coisas do tipo "Ahh, mas eu misturo um monte de letras no meio, troco a ordem de algumas letras, avanço posições como na cifra de César, etc".
Se você ainda pensa em fazer sua própria cifra, leia isto.


ALGORITMOS DE HASH UNIDIRECIONAL

Uma boa maneira de se armazenar senhas é utilizando algoritmos de hash unidirecional. Em nosso escopo, esse tipo de algoritmo serve para "transformar" uma senha em um conjunto de caracteres que represente essa senha. Cada texto gera uma hash única. Então, não existem dois textos diferentes que geram a mesma hash (na teoria era pra ser assim, mas vamos ver sobre colisões mais pra frente). Mas a sacada está no fato de que a partir de uma hash você não consegue chegar na senha. Exemplificando

A partir da senha, você consegue gerar o hash:

mInh@S3Nh4     ->     3cfde1f0d77afbbe72bc15e33b0959fe   (MD5)


Mas a partir de uma hash você não consegue chegar na senha:

557d64c0d96f2432fad2ec1d0d38f253   (MD5)     ->     ???????????


E como você utiliza isso? Simples.
Imagine que você tem um fórum online. Quando o usuário registra, você pega a senha que ele digitou no formulário de cadastro, gera uma hash com essa senha e armazena SOMENTE a hash no Banco de Dados. Quando ele for fazer login, você pega a senha que ele digitou no formulário de login, gera uma hash com essa senha e compara a hash gerada com a hash do Banco. Se elas forem iguais quer dizer que o usuário digitou a senha certa.

Existem diversas opções de algoritmos de hash. Os mais utilizados são MD5 e SHA-1. Então, entre as que existem, qual escolher?

PENSE DUAS VEZES ANTES DE UTILIZAR MD5

O algoritmo MD5 é muito utilizado hoje em dia, mas eu não recomendo seu uso. Existe uma vulnerabilidade conhecida. Ele pode gerar colisões. Isso quer dizer que dois dados distintos podem dar origem a uma mesma hash. 

Para entender um exemplo de qual pode ser a consequência disso, imagine um caso hipotético onde você tem uma senha de 150 caracteres, com letras maiúsculas e minúsculas, dígitos e símbolos, mas que o hash MD5 dessa senha é o mesmo hash dos caracteres "123". Um atacante conseguiria fazer login na sua conta utilizando a senha 123, mesmo que a sua senha seja outra completamente diferente, com 150 caracteres. 

Mas calma, essas colisões não acontecem tão facilmente. Se quiser saber um pouco mais sobre elas você pode ler neste excelente artigo na Wikipédia.

Ou se preferir, aqui existe um algoritmo que gera colisões de MD5 em Javascript.

Mas o real motivo pelo qual eu recomendo que você NÃO utilize MD5 é o fato de que essa hash é amplamente utilizada e por isso, já existem bancos de dados gigantescos, como é o caso do HashKiller que possui mais de 131 bilhões de hashes registradas. Nesse tipo de site, você coloca a hash e se existir no Banco de Dados deles, eles te retornam o texto correspondente àquela hash. O caso do HashKiller possui hashes de MD5, SHA-1 e NTLM, mas existem muitos outros serviços como este e a maioria deles tem como foco o MD5.

Além disso, é possível fazer ataques do tipo força bruta. Vou falar sobre isso em outro artigo.

Então, a não ser que você tenha um bom motivo para usar MD5, procure outras cifras de criptografia.


PENSE DUAS VEZES ANTES DE UTILIZAR SHA-1

O SHA-1 também possui falhas de colisão como descrito neste artigo.
Eu não o recomendo pelos mesmos motivos do MD5. Existem bancos de dados gigantescos com bilhões de hashes que já foram "decifradas".


QUAL EU DEVO UTILIZAR?

Após pesquisar muito sobre qual algoritmo de hash utilizar eu cheguei a conclusão de que, tudo indica que o melhor algoritmo é o bcrypt. Se você não estiver convencido disso, pode consultar este link, na parte onde está escrito "Storing Passwords" pois lá existem pessoas que entendem bem mais que eu.


SOBRE O ALGORITMO BCRYPT

O bcrypt é um método de criptografia baseado no Blowfish. A principal razão que faz desse algoritmo mais seguro é a implementação da variável "custo" que diz respeito à quantidade de processamento necessário para gerar a hash. Isso significa que quando você for gerar a hash, você especifica quanto processamento será utilizado para gerá-la. Isso torna essa cifra sempre adaptável. Conforme os computadores forem evoluindo e o poder de processamento for aumentando, você pode ir incrementando essa variável "custo".

Vou mostrar alguns exemplos dessa hash.
Gerei uma hash bcrypt a partir da senha 12345 e com custo 4. A hash gerada foi a seguinte:

$2a$04$mtSyNAuKHv3Kf5J.qU3ocu7F6zMm3uNj5y/qZZjm/GoQDilxwcXEG


No início da hash, a parte onde está $04$ nos diz que o custo utilizado para gerar esta hash foi 4.
Existe ainda a opção de colocar um salto, mas não vou abordar isso neste artigo.

Você pode testar gerar hash aqui.



COMO UTILIZAR BCRYPT EM PYTHON?

Algumas pessoas me perguntaram como criptografar senhas com bcrypt no python. Então eu fiz um post sobre isso. Segue o link:

Como utilizar bcrypt em python?



Cabe a você encontrar como utilizar esse método de criptografia em outras linguagens. 

Fico devendo pra vocês um artigo sobre bruteforce e um sobre saltos em criptografia.

Até mais.


Nenhum comentário:

Postar um comentário