Ir para conteúdo

POWERED BY:

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 violin101
      Caros amigos, saudações.
       
      Por favor, me permita tirar uma dúvida com os amigos.

      Tenho um Formulário onde o Usuário digita todos os Dados necessários.

      Minha dúvida:
      --> como faço após o usuário digitar os dados e salvar, o Sistema chamar uma Modal ou mensagem perguntando se deseja imprimir agora ?

      Grato,
       
      Cesar
    • Por Carcleo
      Tenho uma abela de usuarios e uma tabela de administradores e clientes.
      Gostaria de uma ajuda para implementar um cadastro
       
      users -> name, login, passord (pronta) admins -> user_id, registratiom, etc.. client -> user_id, registratiom, etc...
      Queria ajuda para extender de user as classes Admin e Client
      Olhem como estáAdmin
      <?php namespace App\Models; use Illuminate\Database\Eloquent\Factories\HasFactory; use Illuminate\Database\Eloquent\Model; class Admin extends User {     use HasFactory;            protected $fillable = [         'name',         'email',         'password',         'registration'     ];      private string $registration;     public function create(         string $name,          string $email,          string $password,         string $registration     )     {         //parent::create(['name'=>$name, 'email'=>$email, 'password'=>$password]);         parent::$name = $name;         parent::$email = $email;         parent::$password = $password;         $this->registration = $registration;     } } User
      <?php namespace App\Models; // use Illuminate\Contracts\Auth\MustVerifyEmail; use Illuminate\Database\Eloquent\Factories\HasFactory; use Illuminate\Foundation\Auth\User as Authenticatable; use Illuminate\Notifications\Notifiable; use Illuminate\Database\Eloquent\Relations\BelongsToMany; class User extends Authenticatable {     /** @use HasFactory<\Database\Factories\UserFactory> */     use HasFactory, Notifiable;     static string $name;     static string $email;     static string $password;     /**      * The attributes that are mass assignable.      *      * @var list<string>      */     protected $fillable = [         'name',         'email',         'password',     ];          /**      * The attributes that should be hidden for serialization.      *      * @var list<string>      */     protected $hidden = [         'remember_token',     ];     /**      * Get the attributes that should be cast.      *      * @return array<string, string>      */     protected function casts(): array     {         return [             'email_verified_at' => 'datetime',             'password' => 'hashed',         ];     }          public function roles() : BelongsToMany {         return $this->belongsToMany(Role::class);     }       public function hasHole(Array $roleName): bool     {                 foreach ($this->roles as $role) {             if ($role->name === $roleName) {                 return true;             }         }         return false;     }         public function hasHoles(Array $rolesName): bool     {                 foreach ($this->roles as $role) {             foreach ($rolesName as $rolee) {             if ($role->name === $rolee) {                 return true;             }          }         }         return false;     }         public function hasAbility(string $ability): bool     {         foreach ($this->roles as $role) {             if ($role->abilities->contains('name', $ability)) {                 return true;             }         }         return false;     }     } Como gravar um Admin na tabela admins sendo que ele é um User por extensão?
      Tentei assim mas é claro que está errado...
      public function store(Request $request, Admin $adminModel) {         $dados = $request->validate([             "name" => "required",             "email" => "required|email",             "password" => "required",             "registration" => "required"         ]);         $dados["password"] =  Hash::make($dados["password"]);                  $admin = Admin::where("registration",  $dados["registration"])->first();                  if ($admin)              return                    redirect()->route("admin.new")                             ->withErrors([                                 'fail' => 'Administrador já cadastrados<br>, favor verificar!'                   ]);                            $newAdmin = $adminModel->create(                                    $dados['name'],                                    $dados['email'],                                    $dados['password'],                                    $dados['registration']                                 );         dd($newAdmin);         $adminModel->save();         //$adminModel::create($admin);                  return redirect()->route("admin.new")->with("success",'Cadastrado com sucesso');     }  
    • Por violin101
      Caros amigos, saudações.
       
      Gostaria de tirar uma dúvida com os amigos, referente a PDV.
       
      Estou escrevendo um Sistema com Ponto de Vendas, a minha dúvida é o seguinte, referente ao procedimento mais correto.

      Conforme o caixa vai efetuando a venda, o Sistema de PDV já realiza:
      a baixa direto dos produtos no estoque
      ou
      somente após concretizar a venda o sistema baixa os produtos do estoque ?
       
      Grato,
       
      Cesar
       
    • Por violin101
      Caros amigos do grupo, saudações e um feliz 2025.
       
      Estou com uma pequena dúvida referente a Teclas de Atalho.

      Quando o Caps Lock está ativado o Comando da Tecla de Atalho não funciona.
      ou seja:
      se estiver para letra minúscula ====> funciona
      se estiver para letra maiúscula ====> não funciona
       
      Como consigo evitar essa falha, tanto para Letra Maiúscula quanto Minúscula ?

      o Código está assim:
      document.addEventListener( 'keydown', evt => { if (!evt.ctrlKey || evt.key !== 'r' ) return;// Não é Ctrl+r, portanto interrompemos o script evt.preventDefault(); });  
      Grato,
       
      Cesar
    • Por violin101
      Caros amigos, saudações.
       
      Por favor, poderiam me ajudar.

      Estou com a seguinte dúvida:
      --> como faço para para implementar o input código do produto, para quando o usuário digitar o ID o sistema espera de 1s a 2s, sem ter que pressionar a tecla ENTER.

      exemplo:
      código   ----   descrição
           1       -----   produto_A
       
      Grato,
       
      Cesar
×

Informação importante

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