Desde que aprendi PHP, me disseram pra armazenar no banco de dados o hash das senhas dos usuarios, particularmente aplicando o algoritmo MD5. Mas hoje fiquei com uma pulga atras da orelha e resolvi pesquisar para saber se este e o metodo mais adequado para tal fim. E, adivinha so: nao e. Topei com dois artigos muito bons que explicam um metodo muito mais seguro: utilizando a funcao crypt().Primeiro, apresento como nao armazenar senhas no banco de dados, e porque.Nao salve as senhas como texto puroIsto deveria ser obvio. Se alguem conseguir acessar seu banco de dados, todos as contas de usuario estarao comprometidas. E nao e so isso: as pessoas tendem a usar a mesma senha em sites diferentes, dai estas outras contas estariam comprometidas tambem. Seu site nem precisaria ser hackeado; um administrador do sistema de um servidor compartilhado poderia facilmente ver seu banco de dados.Nao invente um sistema de seguranca de senhasE muito provavel que voce nao seja um expert em seguranca. E melhor usar uma solucao que funcione comprovadamente do que voce inventar alguma coisa.Nao 'encripte' senhasA encriptacao pode parecer uma boa ideia, mas o processo e reversivel. Qualquer um com acesso ao seu codigo nao teria problema nenhum em transformar as senhas de volta. Seguranca por obscuridade nao e o suficiente.Nao utilize MD5Armazenar os hashes das senhas e um passo na direcao certa. Funcoes criptograficas como o MD5 sao irreversiveis, o que torna mais dificil descobrir a senha original. Para validar um hash de uma senha, simplesmente aplique o hash na senha novamente quando o usuario fizer login e compare os hashes.$senha = 'swordfish';$hash = md5($senha); // Valor: 15b29ffdce66e10527a65bc6d71ad94dNote que isto torna impossivel recuperar a senha original do banco de dados. Se um usuario esquece-la, simplesmente gere uma nova.Entao por que nao o MD5? Porque e muito facil fazer uma lista de milhoes de hashes de senhas (uma rainbow table) e comparar os hashes para achar a senha original (o mesmo vale para outros metodos, como SHA-1).O MD5 tambem esta sujeito a forca bruta (tentando todas as combinacoes com um script automatizado), particularmente devido a colisoes. Isto significa que senhas diferentes podem ter o mesmo hash, tornando ainda mais facil encontrar uma que funcione.Nao use um salt universalUm salt ("sal", em traducao livre) e uma string, adicionada a senha, para que a maioria das rainbow tables (ou ataques por dicionario) nao funcionem.$senha = 'swordfish';$salt = 'alguma coisa aleatoria';$hash = md5($salt . $senha); // Valor: 10ca832b34c90eccc658ead13e7485ebIsto e melhor do que aplicar apenas o MD5, mas alguem com acesso ao seu codigo poderia descobrir o salt e gerar uma rainbow table.Maos a obra!Para um sistema mais seguro de armazenamento de senhas, utilizaremos a funcao crypt() com um salt unico. Muitas pessoas acham que um salt precisa ser unico para cada usuario, o que e verdade para muitos casos. Mas com o crypt() podemos usar um salt que e unico para uma determinada senha. O salt utilizado acabara estando dentro do hash da senha - entao nao precisamos armazena-lo separadamente.Gerando um saltPodemos usar a seguinte string como um salt$salt =