Ir para conteúdo

Arquivado

Este tópico foi arquivado e está fechado para novas respostas.

Tiago R. Paza

Trabalhando com criptografia de login com md5()

Recommended Posts

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?

Compartilhar este post


Link para o post
Compartilhar em outros sites

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

Compartilhar este post


Link para o post
Compartilhar em outros sites

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

Compartilhar este post


Link para o post
Compartilhar em outros sites
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

https://crackstation.net/

 

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?

Compartilhar este post


Link para o post
Compartilhar em outros sites

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

Compartilhar este post


Link para o post
Compartilhar em outros sites

@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 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 e link 2) e 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

 

Compartilhar este post


Link para o post
Compartilhar em outros sites

Apenas para complementar a parte sobre Timing-attack, sugiro a leitura do seguinte link:

http://blog.ircmaxell.com/2014/11/its-all-about-time.html

Compartilhar este post


Link para o post
Compartilhar em outros sites

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

Compartilhar este post


Link para o post
Compartilhar em outros sites

Excelente explicação.:thumbsup:

 

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.

Compartilhar este post


Link para o post
Compartilhar em outros sites
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

https://crackstation.net/

 

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.

Compartilhar este post


Link para o post
Compartilhar em outros sites

  • Conteúdo Similar

    • Por landerbadi
      Boa tarde pessoal. Estou tentado fazer uma consulta no banco de dados porém estou tendo dificuldades. Tenho uma tabela chamada "itens" com os seguintes campos: id, item, ativo. Nela tem cadastrado vários itens. No campo ativo eu coloco a letra "S" para informar que este item está ativo no sistema. Por exemplo: 1, casa, S 2, mesa, S 3, cama, S 4, moto S 5, rádio O quinto registro "radio" não está ativo no sistema pois não tem um "S" no campo ativo. E outra tabela chamada "produtos" com os seguintes campos (id, item1, item2, item3) com os seguintes registros: 1, casa, mesa, moto 2, mesa, casa, cama 3, rádio, cama, mesa Eu preciso fazer uma busca na tabela produtos da seguinte maneira: Eu escolho um registro na tabela "itens", por exemplo "mesa". Preciso fazer com que o php me liste todos os registros da tabela "produtos" que contenham a palavra "mesa". Até aqui tudo bem eu consigo listar. Estou fazendo assim: <?php $item = "mesa" $sql = mysqli_query($conn, "SELECT * FROM produtos WHERE item1 LIKE '$item' OR item2 LIKE '$item' OR item3 LIKE '$item' LIMIT 10"); while($aux = mysqli_fetch_assoc($sql)) { $id = $aux["id"]; $item1 = $aux["item1"]; $item2 = $aux["item2"]; $item3 = $aux["item3"]; echo $id . " - " . $item1 . ", " . $item2 . ", " $item3 . "<br>"; } ?> O problema é que está listando todos os registros que contém o item mesa. Eu preciso que o php verifique os demais item e me liste somente os registro em que todos os registros estejam ativos no sistema. No exemplo acima ele não deveria listar o registro 3. pois nesse registro contém o item "radio" e este item não está ativo no sistema. Ou seja, o registro "radio" na tabela itens não possui um "S" na coluna "ativo". Alguém sabe como resolver isso?
    • Por ILR master
      Fala galera.
      Espero que todos estejam bem.
      Seguinte: Tenho um arquivo xml onde alguns campos estão com : (dois pontos), como o exemplo abaixo:
       
      <item>
      <title>
      d sa dsad sad sadasdas
      </title>
      <link>
      dsadas dsa sad asd as dsada
      </link>
      <pubDate>sadasdasdsa as</pubDate>
      <dc:creator>
      d sad sad sa ad as das
      </dc:creator>
      </item>
       
      Meu código:
       
      $link = "noticias.xml"; 
      $xml = simplexml_load_file($link); 
      foreach($xml -> channel as $ite) {     
           $titulo = $ite -> item->title;
           $urltitulo = $ite -> item->link;
           print $urltitulo = $ite -> item->dc:creator;
      } //fim do foreach
      ?>
       
      Esse campo dc:creator eu não consigo ler. Como faço?
       
      Agradeço quem puder me ajudar.
       
      Abs
       
       
    • Por First
      Olá a todos!
       
      Eu estou criando um sistema do zero mas estou encontnrando algumas dificuldades e não estou sabendo resolver, então vim recorrer ajuda de vocês.
      Aqui está todo o meu código: https://github.com/PauloJagata/aprendizado/
       
      Eu fiz um sistema de rotas mas só mostra o conteúdo da '/' não sei porque, quando eu tento acessar o register nada muda.
      E eu também quero que se não estiver liberado na rota mostra o erro de 404, mas quando eu tento acessar um link inválido, nada acontece.
      Alguém pode me ajudar com isso? E se tiver algumas sugestão para melhoria do código também estou aceitando.
       
       
      Desde já, obrigado.
    • Por landerbadi
      Olá pessoal, boa tarde
       
      Tenho uma tabela chamada "produtos" com os seguintes campos (id, produto) e outra tabela chamada "itens" com os seguintes campos (id, prod_01, prod_02, prod_03, prod_04).
       
      Na tabela produtos eu tenho cadastrado os seguintes produtos: laranja, maçã, uva, goiaba, arroz, feijão, macarrão, etc.
       
      Na tabela itens eu tenho cadastrado os itens da seguinte maneira:
       
      1, laranja, uva, arroz, feijão;
      2, maçã, macarrão, goiaba, uva;
      3, arroz, feijão, maçã, azeite
       
      Meu problema é o seguinte: 
      Eu escolho um produto da tabela "produtos", por exemplo "uva".  Preciso fazer uma consulta na tabela "itens" para ser listado todos os registros que contenham o produto "uva" e que todos os demais produtos estejam cadastrados na tabela "produtos".
       
      No exemplo acima seria listado apenas dois registros, pois o terceiro registro não contém o produto "uva". 
       
      Alguém pode me ajudar? Pois estou quebrando a cabeça a vários dias e não consigo achar uma solução.
    • Por landerbadi
      Boa tarde pessoal. Estou tentado fazer uma consulta no banco de dados porém estou tendo dificuldades. Tenho uma tabela chamada "itens" com os seguintes campos: id, item, plural, ativo. Nela tem cadastrado vários itens e seu respectivo plural. No campo ativo eu coloco a letra "S" para informar que esta palavra está ativa no sistema. Por exemplo: 1, casa, casas, S 2, mesa, mesas, S 3, cama, camas, S 4, moto, motos, S 5, rádio, rádios O quinto registro "radio" não está ativo no sistema pois não tem um "S" no campo ativo. E outra tabela chamada "variações" com os seguintes campos (id, item1, item2, item3) com os seguintes registros: 1, casa, camas, moto 2, mesas, casas, radio 3, rádio, cama, mesa Eu preciso fazer uma busca na tabela variações da seguinte maneira: Eu escolho um registro na tabela "itens", por exemplo "casa". Preciso fazer com que o php me liste todos os registros da tabela "variações" que contenham a palavra "casa". Porém se tiver algum registro com a palavra "casas" também tem que ser listado. Neste caso ele irá encontrar dois registros. Agora eu preciso que o php verifique os demais itens e faça a listagem apenas dos item que estão ativos (que contenham um "S" no campo ativo. Neste caso ele irá encontrar apenas um registro, pois o segundo registro contém a palavra "rádio". E "rádio" não está ativo na tabela itens. Como faço isso?
×

Informação importante

Ao usar o fórum, você concorda com nossos Termos e condições.