A segurança de dados sensíveis dos usuários é sempre um fator determinante para a integridade de qualquer aplicação. Dada essa premissa, esforços são constantes nessa área para prover os sistemas computacionais de formatos criptografados cada vez mais seguros.
Senhas geralmente são armazenadas em hash, que nada mais é do que um símbolo derivado de um algoritmo que o torna incapaz de, à luz da teoria, obter seu estado original. Apesar do nível de complexidade de algoritmos que geram hashes, temos hoje diversas formas que tentam recuperar dados originais “escondidos” através de dicionários, rainbow tables ou força bruta.
Pensando nisso, desenvolvedores da linguagem PHP, preocupados não só com a integridade de senhas mas também com a facilidade de programação oferecida pela linguagem, optaram por criar uma API nativa capaz de somar ao mesmo tempo segurança e simplicidade para armazenamento de credenciais. Criaram então uma extensão de criptografia chamada Password Hashing, disponível desde a versão 5.5.0. Essa extensão utiliza o algoritmo bcrypt, o mais forte suportado pelo PHP atualmente.
Recursos oferecidos
A API oferece um pequeno e poderoso conjunto de funções capazes de auxiliar o programador a criar hashes seguros, realizando todo o trabalho braçal de forma segura e com alto grau de confiabilidade. A seguir, suas respectivas funções:
password_hash
Cria um novo hash de senha usando um algoritmo de hashing. O caso geral para esta função é atribuir um custo (potência matemática) razoável para o algoritmo e deixá-lo criar um salt (parâmetro que gera aleatoriedade da saída) qualquer. O uso de bcrypt sempre retornará uma string de 60 caracteres.
<?php echo password_hash("imasters", PASSWORD_BCRYPT, [ "cost" => 12, // Se omitido, custo 10 'salt' => mcrypt_create_iv(22, MCRYPT_DEV_URANDOM) // Você pode omitir este parâmetro para geração de salt aleatório também. ] ); // Resultado $2y$12$syPYpcHYHWfyraREZ5BCc./OiKezWghwO/5HsbvNv0U4G1xqjsguW
Observação: O $2y$ indica qual algoritmo está sendo utilizado (no caso, bcrypt). O $12$ indica o custo do algoritmo (potência). E, por fim, a parte restante representa o hash gerado.
password_verify
Verifica se uma senha corresponde a um hash.
<?php if(password_verify('imasters', '$2y$12$sy...')) echo 'Senha válida!'; else echo 'Senha inválida!';
password_get_info
Retorna informações sobre o hash dado como algoritmo usado e custo.
<?php var_dump(password_get_info('$2y$12$sy...'));
password_needs_rehash
Verifica se um determinado hash corresponde a informações fornecidas. Caso não seja, assume-se que ele precisa sofrer o processo de hash novamente. Como a função retorna apenas um valor booleano, seu real uso pode ser observado abaixo, quando troco as configurações de geração de hash, ou seja, a senha é válida para aquele algoritmo, mas não para o novo custo que inseri, então gero o hash novamente para a nova configuração.
<?php $senha = 'imasters'; $hash = '$2y$12$sy...'; if(password_verify('imasters', $hash)) { echo "A senha é válida\n"; if(password_needs_rehash($hash, PASSWORD_BCRYPT, ['cost' => 11])) { // Mudei o custo para 11 echo "Senha precisa de novo hash\n"; $hash = password_hash($senha, PASSWORD_BCRYPT, ['cost' => 11]); // Gerei o novo hash echo $hash; // Basta salvar no banco de dados agora } else echo "Senha não precisa de novo hash"; } else echo "Senha não verificada";
Conclusões
Neste artigo, mostramos a facilidade e a simplicidade do gerenciamento de senhas com a API Password Hashing, acompanhadas de um poderoso algoritmo, o bcrypt. O grande objetivo desse recurso é fazer com que você se preocupe mais com as funcionalidades da sua aplicação ao usuário e menos com a complexidade da segurança de senhas.
Referências