AVISO LEGAL : Esta resposta foi escrita em 2008.
Desde então, o PHP nos forneceu password_hash
e password_verify
e, desde a sua introdução, eles são o método recomendado de hash e verificação de senha.
A teoria da resposta ainda é uma boa leitura.
TL; DR
Não é
- Não limite os caracteres que os usuários podem inserir para senhas. Somente idiotas fazem isso.
- Não limite o tamanho de uma senha. Se seus usuários quiserem uma frase com um significado supercalifragilístico e especial, não os impeça de usá-la.
- Não retire ou escape HTML e caracteres especiais na senha.
- Nunca armazene a senha do usuário em texto sem formatação.
- Nunca envie uma senha para o seu usuário, exceto quando a perdeu, e você enviou uma senha temporária.
- Nunca, nunca registre senhas de nenhuma maneira.
- Nunca faça hash de senhas com SHA1 ou MD5 ou mesmo SHA256! Os crackers modernos podem exceder 60 e 180 bilhões de hashes / segundo (respectivamente).
- Não misture bcrypt e com a saída bruta de hash () , use a saída hexadecimal ou base64_encode. (Isso se aplica a qualquer entrada que possa ter um desonesto
\0
, o que pode enfraquecer seriamente a segurança.)
Dos
- Use scrypt quando puder; bcrypt se você não puder.
- Use PBKDF2 se você não puder usar bcrypt ou scrypt, com hashes SHA2.
- Redefina as senhas de todos quando o banco de dados estiver comprometido.
- Implemente um comprimento mínimo razoável de 8 a 10 caracteres, além de exigir pelo menos 1 letra maiúscula, 1 letra minúscula, um número e um símbolo. Isso melhorará a entropia da senha, tornando mais difícil a quebra. (Consulte a seção "O que faz uma boa senha?" Para algum debate.)
Por que senhas hash, afinal?
O objetivo por trás do hash de senhas é simples: impedir o acesso malicioso a contas de usuários comprometendo o banco de dados. Portanto, o objetivo do hash de senha é impedir um hacker ou cracker, gastando muito tempo ou dinheiro para calcular as senhas em texto simples. E tempo / custo são os melhores impedimentos em seu arsenal.
Outro motivo pelo qual você deseja um hash bom e robusto nas contas de usuário é dar a você tempo suficiente para alterar todas as senhas no sistema. Se seu banco de dados estiver comprometido, você precisará de tempo suficiente para pelo menos bloquear o sistema, se não alterar todas as senhas no banco de dados.
Jeremiah Grossman, CTO da Whitehat Security, declarou no blog White Hat Security após uma recente recuperação de senha que exigia a quebra de força bruta de sua proteção por senha:
Curiosamente, ao viver esse pesadelo, aprendi MUITO que não sabia sobre quebra de senhas, armazenamento e complexidade. Aprendi a entender por que o armazenamento de senhas é muito mais importante que a complexidade das senhas. Se você não sabe como sua senha é armazenada, tudo em que realmente pode depender é da complexidade. Isso pode ser um conhecimento comum para profissionais de senhas e criptografia, mas para o especialista médio do InfoSec ou do Web Security, duvido muito.
(Ênfase minha.)
O que faz uma boa senha, afinal?
Entropia . (Não que eu assine totalmente o ponto de vista de Randall.)
Em resumo, entropia é quanta variação existe dentro da senha. Quando uma senha é apenas letras romanas em minúsculas, são apenas 26 caracteres. Isso não é muita variação. As senhas alfanuméricas são melhores, com 36 caracteres. Mas permitir maiúsculas e minúsculas, com símbolos, tem aproximadamente 96 caracteres. Isso é muito melhor do que apenas letras. Um problema é que, para tornar nossas senhas memoráveis, inserimos padrões - o que reduz a entropia. Opa!
A entropia de senha é aproximada facilmente. O uso de toda a gama de caracteres ascii (aproximadamente 96 caracteres digitáveis) gera uma entropia de 6,6 por caractere, que com 8 caracteres para uma senha ainda é muito baixa (52,679 bits de entropia) para segurança futura. Mas a boa notícia é: senhas mais longas e senhas com caracteres unicode aumentam realmente a entropia de uma senha e dificultam a quebra.
Há uma discussão mais longa sobre entropia de senha no site Crypto StackExchange . Uma boa pesquisa no Google também gera muitos resultados.
Nos comentários, conversei com o @popnoodles, que apontou que a imposição de uma política de senha com comprimento X com X muitas letras, números, símbolos etc. pode reduzir a entropia, na verdade, tornando o esquema de senha mais previsível. Eu concordo. A aleatoriedade, o mais aleatória possível, é sempre a solução mais segura, mas menos memorável.
Até onde eu sei, criar a melhor senha do mundo é um Catch-22. Não é memorável, previsível, muito curto, caracteres unicode demais (difíceis de digitar em um dispositivo Windows / Mobile), muito longo, etc. Nenhuma senha é realmente boa o suficiente para nossos propósitos, portanto, devemos protegê-los como se eles fossem estavam em Fort Knox.
Melhores Práticas
Bcrypt e scrypt são as melhores práticas atuais. O Scrypt será melhor do que o bcrypt a tempo, mas ainda não viu a adoção como padrão pelo Linux / Unix ou pelos servidores da web e ainda não teve análises detalhadas de seu algoritmo publicadas. Mas, ainda assim, o futuro do algoritmo parece promissor. Se você estiver trabalhando com Ruby, há uma gema scrypt que o ajudará, e o Node.js agora tem seu próprio pacote scrypt . Você pode usar o Scrypt no PHP via extensão Scrypt ou Libsodium (ambas estão disponíveis no PECL).
Eu recomendo a leitura da documentação para a função crypt, se você quiser entender como usar o bcrypt, encontrar um bom wrapper ou usar algo como PHPASS para uma implementação mais antiga . Eu recomendo um mínimo de 12 rodadas de bcrypt, se não 15 a 18.
Mudei de idéia sobre o uso do bcrypt quando soube que o bcrypt usa apenas o cronograma de chaves do blowfish, com um mecanismo de custo variável. O último permite aumentar o custo da força bruta de uma senha, aumentando a agenda de chaves já dispendiosa do blowfish.
Práticas médias
Quase não consigo mais imaginar essa situação. O PHPASS suporta PHP 3.0.18 a 5.3, portanto é utilizável em quase todas as instalações imagináveis - e deve ser usado se você não tiver certeza de que seu ambiente suporta bcrypt.
Mas suponha que você não possa usar bcrypt ou PHPASS. O que então?
Tente uma implementação do PDKBF2 com o número máximo de rodadas que seu ambiente / aplicativo / percepção do usuário pode tolerar. O número mais baixo que eu recomendo é 2500 rodadas. Além disso, certifique-se de usar hash_hmac () se estiver disponível para dificultar a reprodução da operação.
Práticas Futuras
O PHP 5.5 é uma biblioteca completa de proteção por senha que abstrai qualquer esforço de trabalhar com o bcrypt. Enquanto a maioria de nós está presa ao PHP 5.2 e 5.3 nos ambientes mais comuns, especialmente em hosts compartilhados, o @ircmaxell criou uma camada de compatibilidade para a próxima API que é compatível com versões anteriores ao PHP 5.3.7.
Recapitulação e isenção de responsabilidade de criptografia
O poder computacional necessário para realmente quebrar uma senha com hash não existe. A única maneira de os computadores "violarem" uma senha é recriá-la e simular o algoritmo de hash usado para protegê-la. A velocidade do hash está linearmente relacionada à sua capacidade de ser forçada a bruto. Pior ainda, a maioria dos algoritmos de hash pode ser facilmente paralelizada para ter um desempenho ainda mais rápido. É por isso que esquemas caros como bcrypt e scrypt são tão importantes.
Você não pode prever todas as ameaças ou vias de ataque e, portanto, deve se esforçar ao máximo para proteger seus usuários com antecedência . Se não o fizer, pode até perder o fato de ter sido atacado até que seja tarde demais ... e você é responsável . Para evitar essa situação, aja de paranóico para começar. Ataque seu próprio software (internamente) e tente roubar credenciais do usuário, ou modificar as contas de outros usuários ou acessar seus dados. Se você não testar a segurança do seu sistema, não poderá culpar ninguém além de si mesmo.
Por fim: eu não sou um criptógrafo. Tudo o que eu disse é a minha opinião, mas acho que é baseado no bom e velho senso comum ... e muita leitura. Lembre-se, seja o mais paranóico possível, torne as coisas o mais difíceis de se intrometer possível e, em seguida, se você ainda estiver preocupado, entre em contato com um hacker de chapéu branco ou criptógrafo para ver o que eles dizem sobre seu código / sistema.