De vez em quando, ouço o conselho "Use o bcrypt para armazenar senhas no PHP, regras do bcrypt".
Mas o que é isso bcrypt
? O PHP não oferece essas funções, a Wikipedia fala sobre um utilitário de criptografia de arquivos e as pesquisas na Web apenas revelam algumas implementações do Blowfish em diferentes idiomas. Agora, o Blowfish também está disponível em PHP mcrypt
, mas como isso ajuda no armazenamento de senhas? Blowfish é uma cifra de uso geral, funciona de duas maneiras. Se puder ser criptografado, poderá ser descriptografado. As senhas precisam de uma função de hash unidirecional.
Qual a explicação?
bcrypt
um algoritmo de hash unidirecional versus um esquema de criptografia na minha resposta . Existe todo esse equívoco quebcrypt
é apenas o Blowfish quando, na verdade, ele possui uma programação de teclas totalmente diferente que garante que o texto simples não possa ser recuperado do texto cifrado sem conhecer o estado inicial da cifra (salt, rounds, key).Respostas:
bcrypt
é um algoritmo de hash escalável com hardware (através de um número configurável de rodadas). Sua lentidão e várias rodadas garantem que um invasor precise implantar fundos e hardware maciços para poder decifrar suas senhas. Adicione a isso os sais por senha (bcrypt
EXIGE sais) e você pode ter certeza de que um ataque é praticamente inviável sem uma quantidade absurda de fundos ou hardware.bcrypt
usa o algoritmo Eksblowfish para hash senhas. Embora a fase de criptografia do Eksblowfish e do Blowfish seja exatamente a mesma, a fase de programação principal do Eksblowfish garante que qualquer estado subsequente dependa do sal e da chave (senha do usuário), e nenhum estado pode ser pré-computado sem o conhecimento de ambos. Devido a essa diferença fundamental,bcrypt
é um algoritmo de hash unidirecional. Você não pode recuperar a senha em texto simples sem conhecer o salt, rounds e key (senha). [ Fonte ]Como usar o bcrypt:
Usando PHP> = 5.5-DEV
As funções de hash de senha agora foram construídas diretamente no PHP> = 5.5 . Agora você pode usar
password_hash()
para criar umbcrypt
hash de qualquer senha:Para verificar uma senha fornecida pelo usuário com relação a um hash existente, você pode usar o seguinte
password_verify()
:Usando PHP> = 5.3.7, <5.5-DEV (também RedHat PHP> = 5.3.3)
Existe uma biblioteca de compatibilidade no GitHub criada com base no código fonte das funções acima, originalmente escritas em C, que fornece a mesma funcionalidade. Depois que a biblioteca de compatibilidade é instalada, o uso é o mesmo que acima (menos a notação abreviada de matriz, se você ainda estiver na ramificação 5.3.x).
Usando PHP <5.3.7 (DEPRECATED)
Você pode usar a
crypt()
função para gerar hashes bcrypt de strings de entrada. Essa classe pode gerar sais automaticamente e verificar os hashes existentes em uma entrada. Se você estiver usando uma versão do PHP maior ou igual a 5.3.7, é altamente recomendável usar a função interna ou a biblioteca compat . Essa alternativa é fornecida apenas para fins históricos.Você pode usar este código assim:
Como alternativa, você também pode usar o Portable PHP Hashing Framework .
fonte
mt_rand()
também é transmitido usando o horário atual e o ID do processo atual. Por favor, vejaGENERATE_SEED()
em/ext/standard/php_rand.h
.crypt()
é revisada por pares e verificada então. O código acima chama PHPcrypt()
, que chama acrypt()
função POSIX . Todo o código acima faz mais ao gerar um sal aleatório (que não precisa ser criptograficamente seguro, o sal não é considerado um segredo) antes de chamarcrypt()
. Talvez você deva fazer uma pequena pesquisa antes de ligar para o lobo.crypt()
) está sujeito a uma vulnerabilidade de segurança anterior à 5.3.7 e é (levemente) ineficiente após a 5.3.7 - detalhes do problema relevante podem ser encontrados aqui . Observe também que a nova API de hash de senha ( retrocompat lib ) agora é o método preferido para implementar o hash de senha bcrypt no seu aplicativo.Então, você quer usar o bcrypt? Impressionante! No entanto, como outras áreas da criptografia, você não deve fazer isso sozinho. Se você precisa se preocupar com algo como gerenciar chaves, armazenar sais ou gerar números aleatórios, está fazendo algo errado.
O motivo é simples: é tão trivialmente fácil estragar o bcrypt . De fato, se você examinar quase todos os trechos de código desta página, notará que está violando pelo menos um desses problemas comuns.
Enfrente, a criptografia é difícil.
Deixe para os especialistas. Deixe para as pessoas cujo trabalho é manter essas bibliotecas. Se você precisa tomar uma decisão, está fazendo algo errado.
Em vez disso, basta usar uma biblioteca. Existem vários, dependendo dos seus requisitos.
Bibliotecas
Aqui está um detalhamento de algumas das APIs mais comuns.
API do PHP 5.5 - (disponível para 5.3.7 ou superior)
A partir do PHP 5.5, uma nova API para hash de senhas está sendo introduzida. Também há uma biblioteca de compatibilidade de calços mantida (por mim) para 5.3.7+. Isso tem o benefício de ser uma implementação revisada por pares e simples de usar.
Realmente, o objetivo é ser extremamente simples.
Recursos:
Zend \ Crypt \ Password \ Bcrypt (5.3.2 ou superior)
Essa é outra API semelhante à do PHP 5.5 e tem um objetivo semelhante.
Recursos:
PasswordLib
Essa é uma abordagem ligeiramente diferente para o hash de senha. Em vez de simplesmente dar suporte ao bcrypt, o PasswordLib suporta um grande número de algoritmos de hash. É principalmente útil em contextos em que você precisa oferecer suporte à compatibilidade com sistemas legados e diferentes que podem estar fora de seu controle. Ele suporta um grande número de algoritmos de hash. E é suportado 5.3.2+
Referências:
PHPASS
Esta é uma camada que suporta bcrypt, mas também suporta um algoritmo bastante forte que é útil se você não tiver acesso ao PHP> = 5.3.2 ... Na verdade, ele suporta o PHP 3.0+ (embora não com o bcrypt).
Recursos
Nota: Não use as alternativas PHPASS que não estão hospedadas no openwall, pois são projetos diferentes !!!
Sobre o BCrypt
Se você notar, cada uma dessas bibliotecas retorna uma única sequência. É por isso que o BCrypt funciona internamente. E há uma tonelada de respostas sobre isso. Aqui está uma seleção que eu escrevi, que não vou copiar / colar aqui, mas link para:
md5
senhas antigas para bcryptEmbrulhar
Existem muitas opções diferentes. A escolha que você escolher depende de você. No entanto, gostaria ALTAMENTE recomendamos que você use uma das bibliotecas acima para lidar com isso para você.
Novamente, se você estiver usando
crypt()
diretamente, provavelmente está fazendo algo errado. Se o seu código estiver usandohash()
(oumd5()
ousha1()
) diretamente, você está quase definitivamente fazendo algo errado.Basta usar uma biblioteca ...
fonte
mt_rand()
tem um período suficientemente alto, mas o valor inicial é de apenas 32 bits. Portanto, o usomt_rand()
efetivamente limita você a apenas 32 bits de entropia. O que, graças ao Problema do aniversário, significa que você tem 50% de chance de colisão com apenas 7k de sais gerados (globalmente). Comobcrypt
aceita 128 bits de sal, é melhor usar uma fonte que possa fornecer todos os 128 bits ;-). (em 128 bits, 50% de chance de colisão acontece no 2e19 hashes) ...mt_rand
euniqid
(e, portanto,lcg_value
erand
) não são primeiras escolhas ...Você encontrará muitas informações em Suficiente com as tabelas Rainbow: o que você precisa saber sobre esquemas de senha segura ou estrutura portátil de hash de senha PHP .
O objetivo é hash a senha com algo lento, para que alguém que obtenha seu banco de dados de senha morra tentando forçá-la (um atraso de 10 ms para verificar uma senha não é nada para você, muito para alguém que tenta forçá-la). O Bcrypt é lento e pode ser usado com um parâmetro para escolher o quão lento é.
fonte
Você pode criar um hash unidirecional com o bcrypt usando a
crypt()
função PHP e passando um sal Blowfish apropriado. A mais importante de toda a equação é que A) o algoritmo não foi comprometido e B) você salta corretamente cada senha . Não use sal de aplicação geral; que abre todo o aplicativo para atacar a partir de um único conjunto de tabelas Rainbow.PHP - Função Crypt
fonte
crypt()
função PHP , que suporta várias funções diferentes de hash de senha. Verifique se você não está usandoCRYPT_STD_DES
ouCRYPT_EXT_DES
- qualquer um dos outros tipos suportados está correto (e inclui bcrypt, sob o nomeCRYPT_BLOWFISH
).crypt
expõe vários hashes de senha, com bcrypt correspondente àCRYPT_BLOWFISH
constante. Atualmente, o Bcrypt é o algoritmo mais forte suportado porcrypt
vários outros que ele suporta são bastante fracos.Edit: 15.01.2013 - Se o seu servidor oferecer suporte, use a solução de martinstoeckli .
Todo mundo quer tornar isso mais complicado do que é. A função crypt () faz a maior parte do trabalho.
Exemplo:
Sei que deve ser óbvio, mas não use 'senha' como sua senha.
fonte
2y
vez de2a
.mcrypt_create_iv($size, MCRYPT_DEV_URANDOM)
como fonte para o sal.bcrypt
usos personalizados do alfabeto .mcrypt_create_iv(17, MCRYPT_DEV_URANDOM)
,str_replace('+', '.', base64_encode($rawSalt))
,$salt = substr($salt, 0, 22);
A versão 5.5 do PHP terá suporte embutido para BCrypt, as funções
password_hash()
epassword_verify()
. Na verdade, são apenas invólucros em torno da funçãocrypt()
e facilitarão o uso correto. Ele cuida da geração de um sal aleatório seguro e fornece bons valores padrão.A maneira mais fácil de usar essas funções será:
Esse código hash a senha com BCrypt (algoritmo
2y
), gera um sal aleatório a partir da fonte aleatória do SO e usa o parâmetro de custo padrão (no momento é 10). A segunda linha verifica se o usuário digitou a senha corresponde a um valor de hash já armazenado.Se você deseja alterar o parâmetro cost, pode fazê-lo assim, aumentando o parâmetro cost em 1, dobra o tempo necessário para calcular o valor do hash:
Ao contrário do
"cost"
parâmetro, é melhor omitir o"salt"
parâmetro, porque a função já faz o possível para criar um sal criptograficamente seguro.Para o PHP versão 5.3.7 e posterior, existe um pacote de compatibilidade , do mesmo autor que fez a
password_hash()
função. Para versões do PHP anteriores 5.3.7 não há suporte paracrypt()
com2y
o algoritmo bcrypt segura unicode. Pode-se substituí-lo por2a
, que é a melhor alternativa para versões anteriores do PHP.fonte
Pensamento atual: os hashes devem ser os mais lentos disponíveis, não os mais rápidos possíveis. Isso suprime os ataques da tabela arco-íris .
Também relacionado, mas por precaução: um invasor nunca deve ter acesso ilimitado à sua tela de login. Para evitar isso: Configure uma tabela de rastreamento de endereço IP que registre cada ocorrência junto com o URI. Se mais de 5 tentativas de login vierem do mesmo endereço IP em um período de cinco minutos, bloqueie com explicação. Uma abordagem secundária é ter um esquema de senha de duas camadas, como os bancos. A colocação de um bloqueio para falhas na segunda passagem aumenta a segurança.
Resumo: diminua a velocidade do invasor usando funções hash demoradas. Além disso, bloqueie muitos acessos ao seu login e adicione uma segunda camada de senha.
fonte
Aqui está uma resposta atualizada para essa pergunta antiga!
A maneira correta de hash senhas no PHP desde 5.5 é com
password_hash()
, e a maneira correta de verificá-las é compassword_verify()
, e isso ainda é verdade no PHP 8.0. Essas funções usam hashes bcrypt por padrão, mas outros algoritmos mais fortes foram adicionados. Você pode alterar o fator de trabalho (efetivamente quão forte é a criptografia) através dospassword_hash
parâmetros.No entanto, embora ainda seja suficientemente forte, o bcrypt não é mais considerado o estado da arte ; chegou um conjunto melhor de algoritmos de hash de senha chamado Argon2 , com as variantes Argon2i, Argon2d e Argon2id. A diferença entre eles (como descrito aqui ):
O suporte ao Argon2i foi adicionado no PHP 7.2, e você solicita assim:
e suporte ao Argon2id foi adicionado no PHP 7.3:
Nenhuma alteração é necessária para verificar as senhas, pois a sequência de hash resultante contém informações sobre quais algoritmos, sal e fatores de trabalho foram usados quando foram criados.
De maneira bem separada (e um tanto redundante), o libsodium (adicionado no PHP 7.2) também fornece hash do Argon2 através das funções
sodium_crypto_pwhash_str ()
esodium_crypto_pwhash_str_verify()
, que funcionam da mesma maneira que os embutidos do PHP. Uma razão possível para usá-las é que o PHP às vezes pode ser compilado sem o libargon2, o que torna os algoritmos do Argon2 indisponíveis para a função password_hash; O PHP 7.2 e superior sempre devem ter o libsodium ativado, mas pode não - mas pelo menos existem duas maneiras de obter esse algoritmo. Aqui está como você pode criar um hash Argon2id com libsodium (mesmo no PHP 7.2, que não possui suporte ao Argon2id):Observe que ele não permite que você especifique um sal manualmente; isso faz parte do ethos da libsodium - não permita que os usuários definam parâmetros para valores que possam comprometer a segurança - por exemplo, nada impede que você passe uma string de sal vazia para a
password_hash
função do PHP ; libsodium não permite que você faça nada tão bobo!fonte
Para senhas do OAuth 2 :
fonte
Como todos sabemos, armazenar a senha em texto não criptografado no banco de dados não é seguro. o bcrypt é uma técnica de senha com hash. É usada para criar segurança de senha. uma das funções surpreendentes do bcrypt é nos salvar dos hackers; é usado para proteger a senha contra ataques de hackers, porque a senha é armazenada na forma bcrypted.
a função password_hash () é usada para criar um novo hash de senha. Ele usa um algoritmo de hash forte e robusto. A função password_hash () é muito compatível com a função crypt (). Portanto, os hashes de senha criados por crypt () podem ser usados com password_hash () e vice-versa. As funções password_verify () e password_hash () são apenas os wrappers da função crypt (), e facilitam muito o uso preciso.
SINTAXE
Atualmente, os seguintes algoritmos são suportados pela função password_hash ():
PASSWORD_DEFAULT PASSWORD_BCRYPT PASSWORD_ARGON2I PASSWORD_ARGON2ID
Parâmetros: Esta função aceita três parâmetros, como mencionado acima e descrito abaixo:
senha : armazena a senha do usuário. algo : É a constante do algoritmo de senha que é usada continuamente enquanto denota o algoritmo que deve ser usado quando o hash da senha ocorrer. options : É uma matriz associativa, que contém as opções. Se isso for removido e não incluir, um sal aleatório será usado e a utilização de um custo padrão ocorrerá. Valor de retorno : retorna a senha com hash em caso de sucesso ou False em caso de falha.
Exemplo :
Os programas abaixo ilustram a função password_hash () no PHP:
RESULTADO
fonte