php - Mesmo número de caracteres no password depois do md5 - Stack Overflow em Português
Estou fazendo um processo de abrir uma modal e cadastrar um usuário. A senha do usuário é modificada para md5();
Após isto a senha fica com 32 caracteres.
Quando o usuário vai carregar os dados do usuário para fazer um update.
Se a senha fosse:
****** <- 6 caracteres
Mostraria no input:
*************************** <- 32 caracteres
Teria alguam forma de saber a quantidade que eram antes de fazer o md5(), ou talvez uma abordagem melhor.
Seria inviavel armazenar a quantidade de caracteres no db para realizar isto.
editada 18/11/15 às 13:04
perguntada 18/11/15 às 12:50
No update o correto não seria solicitar a senha para o usuário como confirmação? Trazer do banco não é uma boa ideia. MD5 já não é mais segura também, devido aos ataques de dicionario, talvez valha a pena considerar usar outro método. – George Wurthmann 18/11/15 às 12:56
O ideal é não exibir a senha preenchida, eu costumo deixar o campo de senha bloqueada e um checkbox para habilitar esse campo, caso ele queira atualizar a senha, ele cadastra uma nova senha. – Jeferson Assis 18/11/15 às 12:56
@GeorgeWurthmann um usuário Administrador poderia alterar a senha de um usuário de nivel inferior sem a necessidade de conhecer a senha do usuário. qual outro metodo você indicaria ? – Gabriel Rodrigues 18/11/15 às 13:02
Em qualquer site, o formulário de atualização de senha vem com valor vazio ou uma quantidade fixa de asteriscos. O que você quer fazer de exibir a quantidade de caracteres da senha é uma falha de segurança. Questão relacionada: Como descriptografar MD5? – Pedro Sanção 18/11/15 às 13:08
Não faz diferença alguma inserir os asteriscos. Não importa o que o site X ou site Y faz.. Normalmente, site sério que faz isso coloca meramente alguns asteriscos para ilustrar. É meramente visual mas não tem necessidade alguma. E outro ponto que comentaram, não dê nenhuma chance de pista que leve a um hacker a entender como é a senha. Se o sujeito sabe que a senha tem 5 ou 8 caracteres, fica menos complicado de quebrar a senha pois nem vai perder tempo com outros tamanhos, entendeu? – Daniel Omine 9/12/15 às 16:16
Teria alguma forma de saber a quantidade de caracteres que eram antes de fazer o md5() ?
De forma segura não! Independente da criptografia que você for usar md5, sha1 ou sha256 trazer a hash para o cliente não seria uma boa forma de resolver o problema.
Existe uma abordagem melhor ?
O Comentário do @Sanção trás 2 abordagens:
1 - Deixe os campos vazios.
Caso o usuário digite algo você entenderá pela quantidade de caracteres no campo que é para fazer um update.
2 - Defina uma quantidade fixa de caracteres.
Caso o usuário de um focus nos caracteres apague-os e deixe ele digitar a nova senha.
Você pode dar um placeholder no input, é semelhante a tela de login do nosso http://pt.stackoverflow.com:
<label>Digite sua Senha:</label>
<input type="password" placeholder="******* Nova senha" size="25">
<input type="password" placeholder="******* Confirmar senha" size="25">
editada 11/12/15 às 15:52
respondida 18/11/15 às 16:07
6.57244 medalhas de ouro1414 medalhas de prata4343 medalhas de bronze
+1 Exatamente, qualquer criptografia vai retornar uma has diferente, eu quero apenas uma forma de poder exibir para o cliente os asteriscos! – Gabriel Rodrigues 18/11/15 às 16:11
Entendi, no caso, use a segunda abordagem! – Junior Moreira 18/11/15 às 16:13
Não há como saber a quantidade de caracteres de uma hash md5, justamente porque ela é de mão única, e esse é seu propósito.
Uma forma de saber quanto era antes seria salvar essa quantidade em um campo da base de dados, o que é complemente inviável na questão de segurança.
Veja o exemplo de alguns sites de banco, você digita sua senha no input que vai somente até 5 caracteres e não exibe mais nada que você digitar após o 5º digito, mesmo sendo apenas asteriscos, ou o exemplo do Linux, que simplesmente não mostra sua senha enquanto você está digitando.
Você poderia fazer como já foi sugerido anteriormente, colocar uma quantidade fixa no seu input e quando o usuário clicar, zerar o campo, seria a solução mais prática e também a mais usada.
Procure também mudar seu método de criptografia para usar um salt+senha, e depois gerar um hash usando SHA512, é mais indicado do que usar apenas md5 e correr o risco de sua senha ser encontrada em uma tabela arco-íris.
E nunca use o nome do usuário como salt.
respondida 18/11/15 às 16:14
1.61822 medalhas de ouro99 medalhas de prata3232 medalhas de bronze
Não é possível voltar o md5. Não de uma maneira prática e rápida.
Não sei porque quer exibir dessa forma, mas nas minhas telas de usuário não mostro o campo senha. Apenas um link "Alterar senha" que abre um modal.
respondida 18/11/15 às 12:57
40322 medalhas de prata77 medalhas de bronze
Não é possível de forma prática. E, se for possível para você, é porque é possível para atacantes externos. Se você viu alguém fazendo, essa pessoa não está levando a segurança a sério.
A propósito, NÃO USE MD5! MD5 é demonstradamente falho para o propósito de segurança. Prefira SHA256, pois mesmo o SHA1 já está sendo abandonado por razões de segurança.
respondida 18/11/15 às 13:24
Uma senha "12345" codificada em SHA256 ou SHA2 ou SHA+QualquerCoisa é tão insegura quanto "12345" em MD5. – Daniel Omine 9/12/15 às 16:37
Sim, com certeza. Senhas comuns são a primeira coisa que um atacante vai tentar usar. Assim como palavras de dicionário. Mas isso não invalida a preocupação com um algoritmo de hash forte. Não é só porque não dá pra ter 100% de segurança que a gente vai aceitar 0%. – Pablo Almeida 9/12/15 às 17:35
A preocupação com o tipo do hash é valida quando o brute force é aplicável. Por isso não é 100% certo afirmar, sem explicar os detalhes, que o MD5 é inseguro e deve-se migrar para outros hashes. Dicionários e rainbowtables não incluem salts. Se a senha possuir salt ou um reforço com concatenação, já torna uma rainbow table ou dicionário inválidos. O hacker teria que ter acesso ao salt e gerar uma rainbow table específica desse salt. Se um hacker tem acesso ao DB, ao salt e tudo mais, oras... a falha de segurança não está no hash usado.. né rsrsrs – Daniel Omine 9/12/15 às 19:42
Primeiro, respondendo à pergunta. Sim é possível, se o valor de entrada for igual ao valor existente no banco de dados antes de ser criptografado.
Criptografando o valor de entrada e comparado ao valor já existente, consegue-se o mesmo retorno.
function senha($arg){
$md5 = md5($arg, true);
return substr($md5, 0, 22);
print senha('1234');
$senha_armazenada = senha('1234');
if($senha_armazenada === senha('1234')){
print "senha confere";
print "senha nao confere";
Contudo funções criptográficas como md5, sha1 e por adiante, são consideradas impróprias para tarefas como estas, por serem "fáceis" de quebrar. Apesar de parecerem indestrutíveis, atualmente existe imenso poder de processamento e imensas técnicas para se obter o verdadeiro valor dessa hash.
Para criar uma hash segura, atualmente existem 2 importantes fatores a ter em conta:
O custo (tempo que o computador vai levar a gerar essa hash).
O salt (um incremento único, que torna as hash únicas para cada caso).
O PHP >= 5.5.0 possui funções nativas para criar, verificar hashes seguras, sem muito esforço. Para versões mais antigas PHP < 5.5.0, existem formas de obter o mesmo resultado, também explicado aqui.
Em vez de usar md5, podes usar as funções nativas do PHP >= 5.5.0 para criar algo mais seguro.
header("Contet-Type: text/html; charset=utf-8;");
'nome'=>'Edilson',
'hash'=>'$2y$10$i260FJQg7VgsNjXl6s9Mje9aqXUGbfa9L/c8bA2NOUHyDVoyJoyQu'
'nome'=>'Samuel',
'hash'=>'$2y$10$r1wD4rLLgB1jm6ExF.Em5eyKXdK4Wn8f6z.G9fsxmc3xXay4.pI/O'
function logar($usuario, $senha){
global $usuarios;
foreach($usuarios as $key=>$set){
if(in_array($usuario, $set)){
if(password_verify($senha, $set['hash'])){
function cadastrar($usuario, $senha){
if(!empty($usuario) && !empty($senha)){
$hash = password_hash($senha, PASSWORD_BCRYPT);
$id = mt_rand(3,50);
if(array_push($usuarios, array('id'=>$id, 'nome'=>$usuario, 'hash'=>$hash))){
//var_dump(cadastrar('Edilson','password')); # (true/cadastrado)
var_dump(logar('Edilson', 'password')); # (true/logado)
var_dump(logar('Samuel', '1234')); # (true/logado)print_r($usuarios);
Aqui por exemplo, a variável $usuarios funciona como uma tabela no banco de dados, e quando a função logado é chamada, ela procura nessa array, a hash correspondente, e compara, atravez da função password_verify, que retorna true caso as duas sejam sejam iguais, ou false, caso falhe a comparação.
respondida 18/11/15 às 17:44
4.64111 medalhas de ouro1212 medalhas de prata3939 medalhas de bronze
O md5() é irreversível, a senha criptografada não é acessível, a quantidade de caracteres sempre será 32, o rash do md5 pode se repetir mesmo que tenham senhas de diferentes caracteres. Uma das maneiras seguras de criar senhas é através do password_hash do php.net.