Quão mais seguro é esse do que o MD5 comum ? Acabei de começar a investigar a segurança da senha. Eu sou muito novo em PHP.
$salt = 'csdnfgksdgojnmfnb';
$password = md5($salt.$_POST['password']);
$result = mysql_query("SELECT id FROM users
WHERE username = '".mysql_real_escape_string($_POST['username'])."'
AND password = '$password'");
if (mysql_num_rows($result) < 1) {
/* Access denied */
echo "The username or password you entered is incorrect.";
}
else {
$_SESSION['id'] = mysql_result($result, 0, 'id');
#header("Location: ./");
echo "Hello $_SESSION[id]!";
}
Respostas:
A maneira mais fácil de proteger seu esquema de armazenamento de senhas é usando uma biblioteca padrão .
Como a segurança tende a ser muito mais complicada e com mais possibilidades de confusão invisíveis do que a maioria dos programadores poderia enfrentar sozinha, o uso de uma biblioteca padrão é quase sempre a opção mais fácil e segura (se não a única) disponível.
A nova API de senha do PHP (5.5.0+)
Se você estiver usando o PHP versão 5.5.0 ou mais recente, poderá usar a nova API de hash de senha simplificada
Exemplo de código usando a API de senha do PHP:
(Caso você ainda esteja usando o legado 5.3.7 ou mais recente, você pode instalar o ircmaxell / password_compat para ter acesso às funções internas )
Melhorando os hashes salgados: adicione pimenta
Se você deseja segurança extra, o pessoal de segurança agora (2017) recomenda adicionar uma ' pimenta ' aos hashes de senha com sal (automaticamente).
Há uma queda simples na classe que implementa esse padrão com segurança, eu recomendo: Netsilik / PepperedPasswords ( github ).
Ele vem com uma licença MIT, para que você possa usá-lo como quiser, mesmo em projetos proprietários.
Exemplo de código usando
Netsilik/PepperedPasswords
:A biblioteca padrão OLD
Dê uma olhada em: Estrutura portátil de hash de senha PHP : phpass e certifique-se de usar o
CRYPT_BLOWFISH
algoritmo, se possível.Exemplo de código usando phpass (v0.2):
O PHPass foi implementado em alguns projetos bastante conhecidos:
O bom é que você não precisa se preocupar com os detalhes, esses detalhes foram programados por pessoas com experiência e revisados por muitas pessoas na internet.
Para obter mais informações sobre esquemas de armazenamento de senhas, leia a postagem no blog de Jeff : Você provavelmente está armazenando senhas incorretamente
Faça o que fizer, se você vai para o ' eu vou fazer isso sozinho, obrigado abordagem', não use
MD5
ouSHA1
mais . Eles são um bom algoritmo de hash, mas são considerados quebrados por questões de segurança .Atualmente, o uso da cripta , com CRYPT_BLOWFISH é a melhor prática.
CRYPT_BLOWFISH no PHP é uma implementação do hash Bcrypt. O Bcrypt é baseado na cifra de bloco Blowfish, usando sua configuração de chave dispendiosa para retardar o algoritmo.
fonte
Seus usuários ficarão muito mais seguros se você usar consultas parametrizadas em vez de concatenar instruções SQL. E o salt deve ser exclusivo para cada usuário e deve ser armazenado junto com o hash da senha.
fonte
Uma maneira melhor seria que cada usuário tivesse um sal único.
A vantagem de ter sal é que dificulta ao invasor pré-gerar a assinatura MD5 de cada palavra do dicionário. Mas se um invasor descobrir que você tem um salt fixo, ele poderá gerar previamente a assinatura MD5 de cada palavra do dicionário prefixada pelo seu salt fixo.
Uma maneira melhor é sempre que um usuário altera sua senha, seu sistema gera um sal aleatório e armazena esse sal junto com o registro do usuário. Torna um pouco mais caro verificar a senha (já que você precisa procurar o sal antes de poder gerar a assinatura MD5), mas torna muito mais difícil para um invasor pré-gerar MD5.
fonte
crypt()
função). E como você precisa recuperar o hash da senha, usar um salt específico do usuário não tornará o procedimento mais caro. (Ou você quis dizer que gerar um novo sal aleatório é caro? Acho que não.) Caso contrário, +1.Com o PHP 5.5 (o que eu descrevo está disponível para versões anteriores, veja abaixo) ao virar da esquina, eu gostaria de sugerir o uso de sua nova solução embutida:
password_hash()
epassword_verify()
. Ele fornece várias opções para atingir o nível de segurança de senha que você precisa (por exemplo, especificando um parâmetro "cost" através da$options
matriz)retornará
Como você pode ver, a cadeia contém o sal, bem como o custo especificado nas opções. Ele também contém o algoritmo usado.
Portanto, ao verificar a senha (por exemplo, quando o usuário faz login), ao usar a
password_verify()
função complementar , ele extrai os parâmetros criptográficos necessários do próprio hash da senha.Quando não for especificado um salt, o hash da senha gerada será diferente a cada chamada
password_hash()
porque o salt é gerado aleatoriamente. Portanto, a comparação de um hash anterior com um recém-gerado falhará, mesmo para uma senha correta.A verificação funciona assim:
Espero que o fornecimento dessas funções internas em breve forneça melhor segurança de senha em caso de roubo de dados, pois reduz a quantidade de pensamento que o programador precisa colocar em uma implementação adequada.
Existe uma pequena biblioteca (um arquivo PHP) que fornece PHP 5.5
password_hash
no PHP 5.3.7+: https://github.com/ircmaxell/password_compatfonte
password_hash()
epassword_verify
não importa o que a senha (correta ou não) eu usei eu acabar com senha corretaPor mim tudo bem. O Sr. Atwood escreveu sobre a força do MD5 contra as mesas do arco-íris e, basicamente, com um sal comprido como esse, você fica bem (embora alguns números / pontuação aleatórios possam melhorar).
Você também pode olhar para o SHA-1, que parece estar ficando mais popular atualmente.
fonte
Eu quero adicionar:
Para compatibilidade com sistemas antigos, defina frequentemente um limite para o comprimento máximo da senha. Esta é uma política de segurança incorreta: se você definir restrições, defina-as apenas para o comprimento mínimo de senhas.
Para recuperar uma senha esquecida, você deve enviar o endereço pelo qual o usuário pode alterar a senha.
O hash da senha pode estar desatualizado (os parâmetros do algoritmo podem ser atualizados). Usando a função,
password_needs_rehash()
você pode conferir.fonte