Nette Documentation Preview

syntax
Zgoščevanje gesel
*****************

.[perex]
Da bi zagotovili varnost naših uporabnikov, ne shranjujemo njihovih gesel v berljivi obliki, ampak shranimo samo odtis (t.i. hash). Iz odtisa ni mogoče nazaj rekonstruirati prvotne oblike gesla. Pomembno je uporabiti varen algoritem, s katerim odtis ustvarimo. Pri tem nam pomaga razred [api:Nette\Security\Passwords].

→ [Namestitev in zahteve |@home#Namestitev]

Ogrodje samodejno dodaja v DI vsebnik storitev tipa `Nette\Security\Passwords` pod imenom `security.passwords`, do katere pridete tako, da si jo pustite predati s pomočjo [dependency injection |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]
========================================================================

Izberemo, kateri [varen algoritem |https://www.php.net/manual/en/password.constants.php] za generiranje hasha uporabiti in konfiguriramo njegove parametre.

Kot privzeto se uporablja `PASSWORD_DEFAULT`, torej se izbira algoritma prepušča PHP-ju. Algoritem se lahko v novejših različicah PHP spremeni, če se pojavijo novejši, močnejši hash algoritmi. Zato se morate zavedati, da se lahko dolžina nastalega hasha spremeni, in ga shranite na način, ki lahko sprejme dovolj znakov, 255 je priporočena širina.

Primer nastavitve hitrosti zgoščevanja z algoritmom bcrypt s spremembo parametra cost: (leta 2020 je privzeto 10, zgoščevanje gesla traja približno 80ms, za cost 11 je to cca 160ms, za cost 12 približno 320ms, počasneje kot je, boljša je zaščita, pri čemer se hitrost 10-12 že šteje za zadostno zaščito)

```php
// bomo gesla zgoščevali z 2^12 (2^cost) iteracijami algoritma bcrypt
$passwords = new Passwords(PASSWORD_BCRYPT, ['cost' => 12]);
```

S pomočjo dependency injection:
```neon
services:
	security.passwords: Nette\Security\Passwords(::PASSWORD_BCRYPT, [cost: 12])
```


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

Generira hash gesla.

```php
$res = $passwords->hash($password); // Zgošči geslo
```

Rezultat `$res` je niz, ki poleg samega hasha vsebuje tudi identifikator uporabljenega algoritma, njegove nastavitve in kriptografsko sol (naključni podatki, ki zagotavljajo, da se za isto geslo generira drugačen hash). Je torej nazaj združljiv, ko na primer spremenite parametre, tako da se bodo tudi hashi, shranjeni z uporabo prejšnjih nastavitev, lahko preverili. Celoten ta rezultat se shranjuje v podatkovno bazo, zato ni treba shranjevati soli ali nastavitev posebej.


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

Ugotovi, ali dano geslo ustreza danemu odtisu. `$hash` pridobite iz podatkovne baze glede na vneseno uporabniško ime ali e-poštni naslov.

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


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

Ugotovi, ali hash ustreza v konstruktorju navedenim možnostim.

Uporabno je v trenutku, ko na primer spreminjate hitrost zgoščevanja. Preverjanje poteka glede na shranjene nastavitve in če `needsRehash()` vrne `true`, je treba ponovno ustvariti hash, tokrat z novimi parametri, in ga ponovno shraniti v podatkovno bazo. Tako se samodejno "nadgradijo" shranjeni hashi ob prijavi uporabnikov.

```php
if ($passwords->needsRehash($hash)) {
	$hash = $passwords->hash($password);
	// shraniti $hash v podatkovno bazo
}
```

Zgoščevanje gesel

Da bi zagotovili varnost naših uporabnikov, ne shranjujemo njihovih gesel v berljivi obliki, ampak shranimo samo odtis (t.i. hash). Iz odtisa ni mogoče nazaj rekonstruirati prvotne oblike gesla. Pomembno je uporabiti varen algoritem, s katerim odtis ustvarimo. Pri tem nam pomaga razred Nette\Security\Passwords.

Namestitev in zahteve

Ogrodje samodejno dodaja v DI vsebnik storitev tipa Nette\Security\Passwords pod imenom security.passwords, do katere pridete tako, da si jo pustite predati s pomočjo dependency injection.

use Nette\Security\Passwords;

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

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

Izberemo, kateri varen algoritem za generiranje hasha uporabiti in konfiguriramo njegove parametre.

Kot privzeto se uporablja PASSWORD_DEFAULT, torej se izbira algoritma prepušča PHP-ju. Algoritem se lahko v novejših različicah PHP spremeni, če se pojavijo novejši, močnejši hash algoritmi. Zato se morate zavedati, da se lahko dolžina nastalega hasha spremeni, in ga shranite na način, ki lahko sprejme dovolj znakov, 255 je priporočena širina.

Primer nastavitve hitrosti zgoščevanja z algoritmom bcrypt s spremembo parametra cost: (leta 2020 je privzeto 10, zgoščevanje gesla traja približno 80ms, za cost 11 je to cca 160ms, za cost 12 približno 320ms, počasneje kot je, boljša je zaščita, pri čemer se hitrost 10–12 že šteje za zadostno zaščito)

// bomo gesla zgoščevali z 2^12 (2^cost) iteracijami algoritma bcrypt
$passwords = new Passwords(PASSWORD_BCRYPT, ['cost' => 12]);

S pomočjo dependency injection:

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

hash(string $password): string

Generira hash gesla.

$res = $passwords->hash($password); // Zgošči geslo

Rezultat $res je niz, ki poleg samega hasha vsebuje tudi identifikator uporabljenega algoritma, njegove nastavitve in kriptografsko sol (naključni podatki, ki zagotavljajo, da se za isto geslo generira drugačen hash). Je torej nazaj združljiv, ko na primer spremenite parametre, tako da se bodo tudi hashi, shranjeni z uporabo prejšnjih nastavitev, lahko preverili. Celoten ta rezultat se shranjuje v podatkovno bazo, zato ni treba shranjevati soli ali nastavitev posebej.

verify(string $password, string $hash)bool

Ugotovi, ali dano geslo ustreza danemu odtisu. $hash pridobite iz podatkovne baze glede na vneseno uporabniško ime ali e-poštni naslov.

if ($passwords->verify($password, $hash)) {
	// pravilno geslo
}

needsRehash(string $hash): bool

Ugotovi, ali hash ustreza v konstruktorju navedenim možnostim.

Uporabno je v trenutku, ko na primer spreminjate hitrost zgoščevanja. Preverjanje poteka glede na shranjene nastavitve in če needsRehash() vrne true, je treba ponovno ustvariti hash, tokrat z novimi parametri, in ga ponovno shraniti v podatkovno bazo. Tako se samodejno „nadgradijo“ shranjeni hashi ob prijavi uporabnikov.

if ($passwords->needsRehash($hash)) {
	$hash = $passwords->hash($password);
	// shraniti $hash v podatkovno bazo
}