Hashing de senha
Para gerenciar a segurança de nossos usuários, nunca armazenamos suas senhas em formato de texto simples, em vez disso, armazenamos o hash da senha. O hash não é uma operação reversível, a senha não pode ser recuperada. No entanto, a senha pode ser quebrada e para tornar a quebra tão difícil quanto possível, temos que usar um algoritmo seguro. A classe Nette\Security\Passwords nos ajudará com isso.
A estrutura adiciona automaticamente um serviço Nette\Security\Passwords
ao recipiente DI sob o nome
security.passwords
, que você obtém passando-o usando a injeção de dependência:
use Nette\Security\Passwords;
class Foo
{
public function __construct(
private Passwords $passwords,
) {
}
}
__construct($algo=PASSWORD_DEFAULT, array $options=[]): string
Escolhe qual algoritmo seguro é usado para o hashing e como configurá-lo.
O padrão é PASSWORD_DEFAULT
, então a escolha do algoritmo é deixada para PHP. O algoritmo pode mudar nas
versões mais recentes do PHP quando algoritmos mais novos e mais fortes são suportados. Portanto, você deve estar ciente de que
o comprimento do hash resultante pode mudar. Portanto, você deve armazenar o hash resultante de uma forma que possa armazenar
caracteres suficientes, 255 é a largura recomendada.
É assim que você usaria o algoritmo bcrypt e mudaria a velocidade do hashing usando o parâmetro de custo a partir do padrão 10. No ano 2020, com custo 10, o hashing de uma senha leva cerca de 80ms, custo 11 leva 160ms, custo 12 e depois 320ms, a escala é logarítmica. Quanto mais lento, melhor, o custo 10–12 é considerado lento o suficiente para a maioria dos casos de uso:
// vamos hash passwords com 2^12 (2^cost) iterações do algoritmo bcrypt
$passwords = new Passwords(PASSWORD_BCRYPT, ['cost' => 12]);
Com injeção de dependência:
services:
security.passwords: Nette\Security\Passwords(::PASSWORD_BCRYPT, [cost: 12])
hash(string $passwords): string
Gera o hash da senha.
$res = $passwords->hash($password); // Hashes a password
O resultado $res
é uma string que, além do próprio hash, contém o identificador do algoritmo utilizado, suas
configurações e sal criptográfico (dados aleatórios para garantir que um hash diferente seja gerado para a mesma senha).
Portanto, é retrocompatível, por exemplo, se você alterar os parâmetros, os hashes armazenados usando as configurações
anteriores podem ser verificados. Todo este resultado é armazenado no banco de dados, portanto não há necessidade de armazenar
sal ou configurações separadamente.
verify(string $password, string $hash): bool
Descobre, se a senha dada corresponde ao hash dado. Obtenha o $hash
do banco de dados por nome de usuário ou
endereço de e-mail.
if ($passwords->verify($password, $hash)) {
// Corrigir senha
}
needsRehash(string $hash): bool
Descobre se o hash corresponde às opções dadas no construtor.
Use este método quando, por exemplo, você estiver mudando os parâmetros de hashing. A verificação de senha utilizará
parâmetros armazenados com o hash e se needsRehash()
retornar verdadeiro, você terá que calcular o hash
novamente, desta vez com os parâmetros atualizados, e novamente armazená-lo no banco de dados. Isto assegura que os hashes de
senhas serão automaticamente „atualizados“ quando os usuários estiverem fazendo o login.
if ($passwords->needsRehash($hash)) {
$hash = $passwords->hash($password);
// armazenar $hash para banco de dados
}