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.

Instalação e requisitos

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
}
versão: 4.0