Nette Documentation Preview

syntax
Hashing de senhas
*****************

.[perex]
Para garantir a segurança de nossos usuários, não armazenamos suas senhas em formato legível, mas armazenamos apenas uma impressão digital (o chamado hash). A partir da impressão digital, não é possível reconstruir a forma original da senha. É importante usar um algoritmo seguro para criar a impressão digital. A classe [api:Nette\Security\Passwords] nos ajuda com isso.

→ [Instalação e requisitos |@home#Instalação]

O framework adiciona automaticamente ao contêiner DI um serviço do tipo `Nette\Security\Passwords` com o nome `security.passwords`, ao qual você pode acessar solicitando-o através de [injeção de dependência |dependency-injection:passing-dependencies].

```php
use Nette\Security\Passwords;

class Foo
{
	public function __construct(
		private Passwords $passwords,
	) {
	}
}
```


__construct($algo=PASSWORD_DEFAULT, array $options=[]): string .[method]
========================================================================

Escolhemos qual [algoritmo seguro|https://www.php.net/manual/en/password.constants.php] usar para gerar o hash e configuramos seus parâmetros.

Por padrão, usa-se `PASSWORD_DEFAULT`, ou seja, a escolha do algoritmo é deixada para o PHP. O algoritmo pode mudar em versões mais recentes do PHP, se algoritmos de hashing mais novos e mais fortes aparecerem. Portanto, você deve estar ciente de que o comprimento do hash resultante pode mudar, e você deve armazená-lo de forma que possa acomodar caracteres suficientes, 255 é a largura recomendada.

Exemplo de configuração da velocidade de hashing com o algoritmo bcrypt alterando o parâmetro cost: (em 2020, o padrão é 10, o hashing da senha leva cerca de 80ms, para cost 11 é cerca de 160ms, para cost 12 cerca de 320ms, quanto mais lento, melhor a proteção, sendo que a velocidade 10-12 já é considerada proteção suficiente)

```php
// vamos hashear as senhas com 2^12 (2^cost) iterações do algoritmo bcrypt
$passwords = new Passwords(PASSWORD_BCRYPT, ['cost' => 12]);
```

Usando injeção de dependência:
```neon
services:
	security.passwords: Nette\Security\Passwords(::PASSWORD_BCRYPT, [cost: 12])
```


hash(string $password): string .[method]
========================================

Gera o hash da senha.

```php
$res = $passwords->hash($password); // Gera o hash da senha
```

O resultado `$res` é uma string que, além do próprio hash, contém também o identificador do algoritmo usado, suas configurações e o sal criptográfico (dados aleatórios que garantem que para a mesma senha seja gerado um hash diferente). É, portanto, retrocompatível; se, por exemplo, você alterar os parâmetros, os hashes armazenados usando as configurações anteriores ainda poderão ser verificados. Todo esse resultado é armazenado no banco de dados, portanto, não é necessário armazenar o sal ou as configurações separadamente.


verify(string $password, string $hash): bool .[method]
======================================================

Verifica se a senha fornecida corresponde à impressão digital fornecida. Obtenha `$hash` do banco de dados de acordo com o nome de usuário ou endereço de e-mail fornecido.

```php
if ($passwords->verify($password, $hash)) {
	// senha correta
}
```


needsRehash(string $hash): bool .[method]
=========================================

Verifica se o hash corresponde às opções especificadas no construtor.

É útil usar quando, por exemplo, você altera a velocidade de hashing. A verificação ocorre de acordo com as configurações armazenadas e, se `needsRehash()` retornar `true`, é necessário criar novamente o hash, desta vez com os novos parâmetros, e armazená-lo novamente no banco de dados. Desta forma, os hashes armazenados são "atualizados" automaticamente durante o login dos usuários.

```php
if ($passwords->needsRehash($hash)) {
	$hash = $passwords->hash($password);
	// armazenar $hash no banco de dados
}
```

Hashing de senhas

Para garantir a segurança de nossos usuários, não armazenamos suas senhas em formato legível, mas armazenamos apenas uma impressão digital (o chamado hash). A partir da impressão digital, não é possível reconstruir a forma original da senha. É importante usar um algoritmo seguro para criar a impressão digital. A classe Nette\Security\Passwords nos ajuda com isso.

Instalação e requisitos

O framework adiciona automaticamente ao contêiner DI um serviço do tipo Nette\Security\Passwords com o nome security.passwords, ao qual você pode acessar solicitando-o através de injeção de dependência.

use Nette\Security\Passwords;

class Foo
{
	public function __construct(
		private Passwords $passwords,
	) {
	}
}

__construct($algo=PASSWORD_DEFAULT, array $options=[])string

Escolhemos qual algoritmo seguro usar para gerar o hash e configuramos seus parâmetros.

Por padrão, usa-se PASSWORD_DEFAULT, ou seja, a escolha do algoritmo é deixada para o PHP. O algoritmo pode mudar em versões mais recentes do PHP, se algoritmos de hashing mais novos e mais fortes aparecerem. Portanto, você deve estar ciente de que o comprimento do hash resultante pode mudar, e você deve armazená-lo de forma que possa acomodar caracteres suficientes, 255 é a largura recomendada.

Exemplo de configuração da velocidade de hashing com o algoritmo bcrypt alterando o parâmetro cost: (em 2020, o padrão é 10, o hashing da senha leva cerca de 80ms, para cost 11 é cerca de 160ms, para cost 12 cerca de 320ms, quanto mais lento, melhor a proteção, sendo que a velocidade 10–12 já é considerada proteção suficiente)

// vamos hashear as senhas com 2^12 (2^cost) iterações do algoritmo bcrypt
$passwords = new Passwords(PASSWORD_BCRYPT, ['cost' => 12]);

Usando injeção de dependência:

services:
	security.passwords: Nette\Security\Passwords(::PASSWORD_BCRYPT, [cost: 12])

hash(string $password): string

Gera o hash da senha.

$res = $passwords->hash($password); // Gera o hash da senha

O resultado $res é uma string que, além do próprio hash, contém também o identificador do algoritmo usado, suas configurações e o sal criptográfico (dados aleatórios que garantem que para a mesma senha seja gerado um hash diferente). É, portanto, retrocompatível; se, por exemplo, você alterar os parâmetros, os hashes armazenados usando as configurações anteriores ainda poderão ser verificados. Todo esse resultado é armazenado no banco de dados, portanto, não é necessário armazenar o sal ou as configurações separadamente.

verify(string $password, string $hash)bool

Verifica se a senha fornecida corresponde à impressão digital fornecida. Obtenha $hash do banco de dados de acordo com o nome de usuário ou endereço de e-mail fornecido.

if ($passwords->verify($password, $hash)) {
	// senha correta
}

needsRehash(string $hash): bool

Verifica se o hash corresponde às opções especificadas no construtor.

É útil usar quando, por exemplo, você altera a velocidade de hashing. A verificação ocorre de acordo com as configurações armazenadas e, se needsRehash() retornar true, é necessário criar novamente o hash, desta vez com os novos parâmetros, e armazená-lo novamente no banco de dados. Desta forma, os hashes armazenados são „atualizados“ automaticamente durante o login dos usuários.

if ($passwords->needsRehash($hash)) {
	$hash = $passwords->hash($password);
	// armazenar $hash no banco de dados
}