Usamos cookies para medir audiência e melhorar sua experiência. Você pode aceitar ou recusar a qualquer momento. Veja sobre o iMasters.
Galera estou trabalhando com criptografia de usuário e senha.
Para isso estou usando o md5()
<?php
$usuario = md5($_POST['usuario']);
$senha = md5($_POST['senha']);
?>
E gravo no banco:
<?php
db::Query("INSERT painel_usuarios(usuario, senha, email, turno, ativo) VALUES ('$usuario','$senha','$email','$turno','$status') ");
?>
A minha dúvida é como posso fazer para o input para o usuário logar com a senha fornecida, pois ele está validando a senha criptografada e se informo a senha original sem criptografia no campo de input ele dá a senha invalida, como solucionar este problema?Você colocou md5 no usuário também?
Quando o usuário digitar a senha no login, jogue o MD5 nela e compare se é igual a que está no banco.
Em primeiro lugar, compreenda o que é HASH e o que é CRIPTOGRAFIA.
http://stackoverflow.com/a/4948393/1628790
Em segundo lugar, não deve ser utilizado md5 para hash de senhas. PHP possui a biblioteca password. Outra, que o login do usuário não deve ter hash.
Para inserir/salvar a senha, deve-se utilizar a função password_hash:
$usuario = $_POST['usuario'];
$senha = password_hash($_POST['senha'] , PASSWORD_DEFAULT);
//e salve no SGBD
Para realizar o login, deve-se utilizar a função password_verify. O código em questão deve ser similar a:
//criado utilizando o seguinte código: password_hash("dummy_password" , PASSWORD_DEFAULT);
define("DUMMY_PASSWORD" , '$2y$10$bev5nl962WWcwa1G2gyXyunkKY77Xf7OTr.1I3zcl7Qd4zFYCqXjC');
$usuario = $_POST['usuario'];
$pdo = new \PDO(/** dados de conexão**/);
$statement = $pdo->prepare('SELECT * FROM user WHERE login = ?');
$statement->execute([$usuario]);
$row = $statement->fetch(PDO::FETCH_ASSOC);
if(!$row)
{
// A validação é feita em uma senha qualquer
//para que o tempo de resposta entre uma consulta que o usuário não exista
//e uma consulta que o usuário exista e a senha esteja errada seja o mesmo.
password_verify("" , DUMMY_PASSWORD);
throw new \RuntimeException('Usuário/Senha não confere');//usuário não existe, mas a mensagem é genérica para evitar força bruta
}
if(!password_verify($_POST['senha'] , $row['password']))
{
throw new \RuntimeException('Usuário/Senha não confere');//usuário existe, mas a mensagem é genérica para evitar força bruta
}
echo 'usuário logado';
Somente reforçando, não utilize MD5, é falho e inseguro.
-------
Update
Para ver a questão da DUMMY_PASSWORD, leia o seguinte artigo: [http://blog.ircmaxell.com/2014/11/its-all-about-time.html](http://blog.ircmaxell.com/2014/11/its-all-about-time.html)@Gabriel Heming, agora fiquei com uma pulga atrás da orelha.
O MD5 é inseguro? Mesmo não sendo um hash "retornável"? Qual a diferença para o próprio do PHP? (primeira vez que o vejo!)
Md5 não é inseguro e o hash já tem função prontas de gerar e verificar não precisa converter!
>
Em 2017-4-19 at 17:11, Maykel-ctba disse:
O MD5 é inseguro?
Primeiro, MD5 foi criado para ser uma criptografia do tipo hash (unidirecional) para criar um fingerprint (impressão digital) de um conjunto de caracteres/bytes (certificados digitais, por exemplo). Entretanto, foram encontradas diversas falhas nele, que, hoje em dia, ele não é mais utilizado para o propósito original.
Tem vários materiais sobre a (in)segurança do MD5.
https://en.wikipedia.org/wiki/MD5#Security
https://security.stackexchange.com/questions/19906/is-md5-considered-insecure
https://security.stackexchange.com/questions/52461/how-weak-is-md5-as-a-password-hashing-function
>
Em 2017-4-19 at 17:11, Maykel-ctba disse:
Mesmo não sendo um hash "retornável"?
Não ser retornável, não quer dizer impossível de ser quebrado. O pensamento "linear" de "quebrar" é possuir um hash e retorná-lo ao estado de origem. Entretanto, não é isso que ocorre.
O MD5 é tão rápido de ser gerado, que pode-se gerar biliões de combinações em pouco espaço de tempo. Você não precisa saber o HASH original, só precisa encontrar um que, quando gerado, seja igual ao outro.
Lembrando que MD5 gera colisões, ou seja, conjuntos de caracteres diferentes podem gerar hashs iguais.
https://en.wikipedia.org/wiki/MD5#Collision_vulnerabilities
https://en.wikipedia.org/wiki/Collision_attack
A forma mais conhecida de "reverter" um MD5 é através de uma rainbow table. Veja por si só no link abaixo
Ou pesquise no google sobre "MD5 Reverse".
>
Em 2017-4-19 at 17:11, Maykel-ctba disse:
Qual a diferença para o próprio do PHP?
No link abaixo você pode ler um pouco sobre como funciona o password_hash:
https://pt.stackoverflow.com/questions/194929/password-hash-php/194950#194950
>
Em 2017-4-19 at 17:33, Progjunior Daniel disse:
Md5 não é inseguro e o hash já tem função prontas de gerar e verificar não precisa converter!
Fale isso para o CERT... http://www.kb.cert.org/vuls/id/836068
Uma das primeiras falhas do MD5 foi encontrada em 1996:
ftp://ftp.rsasecurity.com/pub/cryptobytes/crypto2n2.pdf
Como pode dizer que é seguro?
vivendo e aprendendo... essa função do php eu desconhecia.
particularmente, em todos os meus projetos eu utilizo sha1(md5(string))
Vou passar a analisar e ponderar a utilização dessa função nativa
e password_hash seria melhor apenas que md5 e sha1 ou melhor que sha256, sha364 e sha512 também? porque a hash gerada por ele é de 60 caracteres ou seja mais do que md5 e sha1 mas inferior aos outros 3. sha512 gera hash de 128 caracteres acho que o collide risk é bem menor com sha512 não acha? e talvez vou falar bestera mas e se juntar por exemplo md5 e sha1 pra gerar a senha no banco? não falo de hashear um dentro do outro falo de concatenar as duas hashs acho que aí a chance de colisão seria ainda menor do que usando qualquer um deles sozinho ou será que não? nunca fiz isso estou só imaginando aqui
@marsolim Não é apenas a quantidade de caracteres que influência. Existem N fatores. Algumas das questões que posso afirmar:
- Blowfish é o algorítimo mais poderoso que o PHP possui no momento ([Argon2](https://wiki.php.net/rfc/argon2_password_hash) está planejado para ser lançado com o PHP 7.3);
- Cada identificador utilizado pelo blowfish ($2a$, $2x$ e $2y$), gerará um tipo de hash diferente;
- password_hash cria automaticamente um SALT forte (caso nenhum SALT seja fornecido) para melhorar ainda mais a segurança;
- password_hash tem proteção contra força bruta ([link 1](http://stackoverflow.com/questions/30215781/why-is-phps-password-hash-so-slow) e [link 2](https://en.wikipedia.org/wiki/Key_stretching#Strength_and_time)) e [timing attack](https://en.wikipedia.org/wiki/Timing_attack).
Sobre colisão, todo algorítimo é passível de colisão (há quem diga que não, entretanto, vejo apenas como uma questão de "possível, mas improvável"), o que muda é a probabilidade. MD5 tem uma maior incidência por ser do tipo *footprint* (impressão digital).
O password_hash, por outro lado, gerará hash's aleatórios, determinados pelo salt utilizado. O salt é parte essencial do hash gerado (está dentro dos 60 caracteres). Já que, a probabilidade de se gerar uma colisão sem salt, ou com salt fixo, é alta, com salt aleatório a probabilidade de uma colisão é muito menor.
Algumas questões de segurança, a mais, podem ser verificas no link abaixo que explica sobre o identificador '$2y$':
[http://www.php.net/security/crypt_blowfish.php](http://www.php.net/security/crypt_blowfish.php)Apenas para complementar a parte sobre Timing-attack, sugiro a leitura do seguinte link:
E, para quem quiser se aprofundar mais, leiam os artigos de Scott Arciszewski , ele é um dos "cabeças" no PHP quando se trata de segurança.
Alguns que podem ser de interesse:
https://paragonie.com/blog/2016/02/how-safely-store-password-in-2016
https://paragonie.com/blog/2015/04/secure-authentication-php-with-long-term-persistence
Excelente explicação.
Antes que alguém pergunte... Sim, da pra fazer um SALT e concatenar com a palavra digitada e gerar um MD5, porém, pelos motivos de segurança já expostos acima, o melhor é utilizar a própria função nativa que já faz isso por si só, do contrário estás fazendo uma gambiarra.
>
Em 19/04/2017 at 17:48, Gabriel Heming disse:
Primeiro, MD5 foi criado para ser uma criptografia do tipo hash (unidirecional) para criar um footprint (impressão digital) de um conjunto de caracteres/bytes (certificados digitais, por exemplo). Entretanto, foram encontradas diversas falhas nele, que, hoje em dia, ele não é mais utilizado para o propósito original.
Tem vários materiais sobre a (in)segurança do MD5.
https://en.wikipedia.org/wiki/MD5#Security
https://security.stackexchange.com/questions/19906/is-md5-considered-insecure
https://security.stackexchange.com/questions/52461/how-weak-is-md5-as-a-password-hashing-function
Não ser retornável, não quer dizer impossível de ser quebrado. O pensamento "linear" de "quebrar" é possuir um hash e retorná-lo ao estado de origem. Entretanto, não é isso que ocorre.
O MD5 é tão rápido de ser gerado, que pode-se gerar biliões de combinações em pouco espaço de tempo. Você não precisa saber o HASH original, só precisa encontrar um que, quando gerado, seja igual ao outro.
Lembrando que MD5 gera colisões, ou seja, conjuntos de caracteres diferentes podem gerar hashs iguais.
https://en.wikipedia.org/wiki/MD5#Collision_vulnerabilities
https://en.wikipedia.org/wiki/Collision_attack
A forma mais conhecida de "reverter" um MD5 é através de uma rainbow table. Veja por si só no link abaixo
Ou pesquise no google sobre "MD5 Reverse".
No link abaixo você pode ler um pouco sobre como funciona o password_hash:
https://pt.stackoverflow.com/questions/194929/password-hash-php/194950#194950
Fale isso para o CERT... http://www.kb.cert.org/vuls/id/836068
Uma das primeiras falhas do MD5 foi encontrada em 1996:
ftp://ftp.rsasecurity.com/pub/cryptobytes/crypto2n2.pdf
Como pode dizer que é seguro?
Legal, não sabia dessa matéria! Eu sempre fiz com md5, mas a função que existe do php é um código mais complexo mesmo!!!
Obrigado pelo feedback.
Sobre isso só posso lhe dar um conselho. Use o bcrypt.
ué só fazer a mesma coisa na hora da consulta ou seja criptografar antes de passar ela para a query e não se costuma criptografar outros dado como usuario não até porque tu pode precisar alguma hora printar ele na tela e não tem como descriptografar