Qual a forma correta de se fazer sistema de login seguro em PHP + MySQL?

1. Qual a forma correta de se fazer sistema de login seguro em PHP + MySQL?

Jonas Vinícios Guartieri de Assis
jonasguartieri

(usa Debian)

Enviado em 03/12/2012 - 01:41h

Olá! estou com muita dor de cabeça, portanto, vou direto ao ponto:
Estou desenvolvendo um sistema em PHP + MySQL onde preciso criar um sistema de login para restringir o acesso às páginas. Tentei utilizando PHP e SESSION, mas tive um problema com o método crypt() do php, pois precisava manter a senha criptografada no MySQL e na SESSION ao mesmo tempo, para comparar com o banco de dados constantemente, pois não existe como descriptografar utilizando esse método. MD5 está fora de questão, pois existem sites que podem descriptografá-lo em dois cliques.

Devo manter a senha descriptografada no MySQL e criptografar apenas na hora de armazená-la na session (
$_SESSION['login'] = crypt($Result['pass']) 
]) ou existe alguma forma mais inteligente e segura de fazer isto?

Estou tentando há vários dias, e como comecei utilizar MySQL há pouco tempo, tenho certa dificuldade.

Desde já, obrigado!


  


2. Re: Qual a forma correta de se fazer sistema de login seguro em PHP + MySQL?

Andre Cardoso
andrebian

(usa Fedora)

Enviado em 06/12/2012 - 00:10h

Uma boa dica é vc criptografar diretamente no banco, ou seja, no momento do cadastro do usuário.


// gravação

$email = trim(addslashes($_POST['email']));
$senha = md5( trim(addslashes($_POST['senha'])) );

$query = "insert into nome_da_tabela set email='$email', senha='$senha'";



// comparação

$senhaBanco = $Result['senha']
$senhaDigitada = md5( trim(addslashes($_POST['senha'])) );

if ( $senhaBanco == $senhaDigitada ) {
// executa algo
}




3. Re: Qual a forma correta de se fazer sistema de login seguro em PHP + MySQL?

Jonas Vinícios Guartieri de Assis
jonasguartieri

(usa Debian)

Enviado em 06/12/2012 - 15:22h

Sim andrebian, isso funcionaria, mas eu queria utilizar o método crypt porque o MD5 me parece um pouco menos seguro, pois existem sites que podem quebrá-lo em poucos cliques.

Criei duas funções que efetuam e verificam login com session:

function sqlLogin ($table, $user, $pass) {
@$Result=mysql_query("SELECT * FROM $table WHERE user='$_POST[user]'");
@$Row= mysql_fetch_array($Result);

if (mysql_num_rows($Result) == 1 && crypt($pass, $Row['pass']) == $Row['pass']) {
$_SESSION['login'] = serialize($Row);
return true;
}
else {
session_destroy();
return false;
}
}
function sqlLogged () {
if (@$_GET['action'] == "logout") {
unset($_SESSION['login']);
session_destroy();
header("Location: login.php");
}
return (isset($_SESSION['login'])) ? true : header('Location: login.php');
}


Como pode observar, estou armazenando a senha já criptografada na base de dados e armazeando-a na session para comparar constantemente, no entanto, a comparação é impossibilitada pelo fato de o método crypt gerar uma chave diferente toda vez, fazendo necessaŕia a utilização da seguinte forma de comparação:
if (crypt('textodesencriptado', 'textocritpografado') == 'textocriptografado') { ação ao confirmar }; 
, permitindo que qualquer um que cadastre uma session genérica com nome de 'login' tenha acesso ao meu sistema.


4. Re: Qual a forma correta de se fazer sistema de login seguro em PHP + MySQL?

Andre Cardoso
andrebian

(usa Fedora)

Enviado em 06/12/2012 - 20:12h

bem vamos lá, o md5 é um caminho sem volta, ou seja não há como quebrá-lo, o que realmente ocorre é que alguns hackers, ou melhor, crackers começaram a catalogar diversas combinações para assim poder quebrar a senha dos sites. Com relação a utilizar o crypt sua lógica está correta, o que está ocorrendo podem ser duas coisas:

1 - o usuário está digitando a senha errada (o que na minha opinião é a mais viável visto que mesmo em testes o programador utiliza diversas senhas e pode por exemplo no momento de cadastrar estar desatento a ter adicionado ou deixar faltar algum caracter)

2 - a consulta no banco não está trazendo o resultado esperado.

veja este exemplo como ocorre tudo bem:


$digitada = 'andre';

//$banco = crypt('andre');
// echo $banco;

// Resultado
// $6$PQO3MBfjBA3C$LOAyicQc/Qk.TE9R9wUKeT6ApWCePbn2m/Jm0PrqoFCa1WXRToMB9QsONMw671TLTbc7/oLysXdJeJe30gJ.K.

$banco = '$6$PQO3MBfjBA3C$LOAyicQc/Qk.TE9R9wUKeT6ApWCePbn2m/Jm0PrqoFCa1WXRToMB9QsONMw671TLTbc7/oLysXdJeJe30gJ.K.';

if (crypt($digitada, $banco) == $banco) {
echo "Senha confere";
} else {
echo "Senha não confere";
}



5. Re: Qual a forma correta de se fazer sistema de login seguro em PHP + MySQL?

Jonas Vinícios Guartieri de Assis
jonasguartieri

(usa Debian)

Enviado em 06/12/2012 - 22:30h

Eu consigo comparar o login inserido pelo usuário com o banco de dados perfeitamente. O problema é que eu gostaria de salvar a senha criptografada original do banco na sessão e utilizar uma função que verifica constantemente se a senha armazenada na session é igual a do banco de dados. O objetivo disto é, como eu disse anteriormente, evitar que pessoas mal intencionadas tenham acesso apenas criando uma session genérica.