APIs e Microsserviços

16 set, 2014

Password Hashing – API nativa para gerenciamento de senhas

Publicidade

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