leitura de
Encontrou um problema no conteúdo? Por favor, deixe seu comentário!

Atenção: Esse artigo está desatualizado, por favor leia o meu post mais recente sobre segurança de senhas.

Fala pessoal, tudo bom?

Volta e meia gosto de vir aqui falar um pouquinho sobre “Segurança” e uma das coisas que acho mais interessante - nessa área - e a encriptação de senhas.

Hoje li um artigo muito bom (bem antigo por sinal) no NetTuts+ e achei legal trazer algumas informações pra cá, de forma bem resumida e direta, porém recomendo muito a leitura do artigo original.

Hashing

Hashing consiste em proteger dados (strings, números), convertendo-os em um novo dado, geralmente menor e em formato de string ou inteiro.

Hashes geralmente são mão-única, o que significa que não há uma forma de reverter a encriptação, ou encontrar o dado original baseado no hash (resultado da encriptação).

O problema

Estamos acostumados a usar hashes como MD5 e SHA1 da seguinte forma:

No caso do MD5, resultado final é sempre uma string de 32 caracteres alfa-numéricos (128 bits).

Você pode usar o MD5 e pensar que está seguro, mas existe uma coisa chamada Rainbow Tables, onde um atacante gera uma tabela com o resultado da encriptação de todas as palavras de um dicionário, combinando palavras e até adicionando símbolos e dígitos à essas palavras…. Com essa Rainbow Table fica muito fácil (partindo do resultado final da encriptação) descobrir a senha original (olá mundo).

A solução simples: salts

A solução mais simples é utilizar um “salt” que é uma string complexa que será concatenada a toda e qualquer senha antes de encriptá-la, por exemplo:

Dessa forma, todas as senhas estarão mais protegidas… porém ainda temos um problema:

O problema: salt fixo

  1. Todas as senhas usam o mesmo salt
  2. O salt (que é fixo) está presente em algum arquivo/texto dentro do seu sistema
  3. O invasor que conseguiu pegar o seu banco de dados (de senhas) também vai ter acesso aos arquivos e, consequentemente, ao salt
  4. Com posse do salt o atacante gera uma Rainbow Table nova, usando aquele salt nas combinações

Precisamos então - de alguma forma - proteger o salt, ou gerar um salt novo pra cada senha, o que seria o ideal.

A solução complicada: salts dinâmicos

Podemos gerar uma string aleatória no PHP de várias formas, mas a idéia principal aqui é: gerar uma string aleatória, utilizá-la como salt na hora de encriptar a senha do usuário e salvar AMBAS no banco de dados (a senha e a string utilizada como salt).

Dessa forma, cada senha terá seu próprio salt e o atacante teria que gerar uma rainbow table pra cada salt, o que fica impraticável.

Mas infelizmente ainda temos um problema…

O problema: tempo

A maioria dos métodos de encriptação que conhecemos (como MD5 e SHA1) são criados para serem extremamente rápidos, pois são utilizados na verificação de integridade de arquivos… o que acaba sendo um tiro no pé quando estamos falando de segurança: quanto mais rápido o algoritmo mais fácil um ataque de força-bruta (com ou sem Rainbow Tables) pode conseguir encontrar a senha original.

Precisamos então trocar de algoritmo ou atrasar o nosso script…

A solução: atrasando o algoritmo

Agora qualquer ataque de força-bruta irá demorar 1000x mais para conseguir chegar até sua senha original, o que é excelente!

Finalizando…

O artigo original não termina por aqui, ele sugere a utilização de um algoritmo chamado BLOWFISH que recebe um parâmetro onde você determina o “custo”, que está ligado à demora/ciclos de encriptação… quanto maior, mais demorado.

Espero que tenham entendido a idéia geral e tenham gostado! :)

Thiago Belem / Blog

Thiago Belem


Publicado

Thiago Belem / Blog

Thiago Belem / Blog

Artigos e tutoriais sobre desenvolvimento WEB

Continue lendo