> ## Documentation Index
> Fetch the complete documentation index at: https://kawax.biz/llms.txt
> Use this file to discover all available pages before exploring further.

# Hashing

> Come effettuare hashing sicuro delle password e verificarle usando la facade Hash di Laravel. Configurazione e uso degli algoritmi bcrypt e Argon2.

## Cos'è l'hashing

L'hashing è il processo che, tramite una trasformazione unidirezionale, converte dati in chiaro (come le password) in una stringa di lunghezza fissa.
Dallo stesso input viene sempre generato lo stesso hash, ma non è possibile risalire al testo in chiaro a partire dall'hash.

La facade `Hash` di Laravel supporta gli algoritmi di hashing **bcrypt** e **Argon2** per la conservazione sicura delle password.

### Confronto tra gli algoritmi

| Algoritmo    | Caratteristiche                                                                            | Uso consigliato                             |
| ------------ | ------------------------------------------------------------------------------------------ | ------------------------------------------- |
| **bcrypt**   | Puoi regolare il costo computazionale tramite il work factor (rounds). Predefinito.        | Applicazioni web comuni                     |
| **argon2i**  | Puoi regolare memoria, tempo e numero di thread. Robusto contro gli attacchi side-channel. | Contesti con requisiti di sicurezza elevati |
| **argon2id** | Ibrido tra argon2i e argon2d. Consigliato da PHC.                                          | Progetti nuovi che vogliono usare Argon2    |

<Info>
  Il "work factor" di bcrypt controlla il tempo necessario per generare l'hash. Più l'hashing è lento, più aumenta la resistenza agli attacchi brute-force. Aumentando il work factor con l'evolvere dell'hardware puoi mantenere il livello di sicurezza.
</Info>

### Flusso di hashing e verifica

```mermaid theme={null}
flowchart LR
    A[Password in chiaro] -->|Hash::make| B["Valore hash<br>salvato nel DB"]
    C[Input al login] -->|Hash::check| D{Corrispondono?}
    B --> D
    D -->|true| E[Autenticazione riuscita]
    D -->|false| F[Autenticazione fallita]
```

***

## Configurazione

Di default Laravel usa il driver `bcrypt`. Puoi cambiarlo tramite la variabile d'ambiente `HASH_DRIVER`.

```ini theme={null}
# .env
HASH_DRIVER=bcrypt  # bcrypt / argon / argon2id
```

Per personalizzare la configurazione dell'hashing, pubblica il file di configurazione con `config:publish`.

```shell theme={null}
php artisan config:publish hashing
```

Dopo la pubblicazione puoi modificare il work factor predefinito e altre opzioni in `config/hashing.php`.

***

## Uso di base

### Hashing di una password

Passando la password in chiaro a `Hash::make()` ottieni il valore hash. Questo valore va salvato nel database.

```php theme={null}
<?php

namespace App\Http\Controllers;

use Illuminate\Http\RedirectResponse;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Hash;

class PasswordController extends Controller
{
    public function update(Request $request): RedirectResponse
    {
        $request->validate([
            'password' => ['required', 'min:8', 'confirmed'],
        ]);

        $request->user()->fill([
            'password' => Hash::make($request->password),
        ])->save();

        return redirect('/profile');
    }
}
```

<Warning>
  Salva il valore hash nel database ma non salvare mai la password in chiaro.
</Warning>

### Regolare il work factor di bcrypt

Con l'opzione `rounds` puoi regolare il costo computazionale della generazione dell'hash. Valori più alti sono più sicuri ma richiedono più tempo di elaborazione.
Il valore predefinito (12) è adatto alla maggior parte delle applicazioni.

```php theme={null}
$hashed = Hash::make('plain-text-password', [
    'rounds' => 14,
]);
```

### Regolare il work factor di Argon2

Con Argon2, puoi regolare il costo computazionale tramite le opzioni `memory`, `time` e `threads`.

```php theme={null}
$hashed = Hash::make('plain-text-password', [
    'memory'  => 65536, // in KiB
    'time'    => 4,
    'threads' => 2,
]);
```

| Opzione   | Descrizione                     | Predefinito |
| --------- | ------------------------------- | ----------- |
| `memory`  | Quantità di memoria usata (KiB) | 65536       |
| `time`    | Numero di iterazioni            | 4           |
| `threads` | Numero di thread usati          | 1           |

<Tip>
  Per i dettagli sulle opzioni di Argon2 consulta la [documentazione ufficiale di PHP](https://secure.php.net/manual/en/function.password-hash.php).
</Tip>

***

## Verifica delle password

Con `Hash::check()` puoi verificare se una password in chiaro corrisponde all'hash salvato.
È il caso tipico d'uso all'interno del processo di login.

```php theme={null}
use Illuminate\Support\Facades\Hash;

if (Hash::check($request->password, $user->password)) {
    // La password corrisponde
} else {
    // La password non corrisponde
}
```

Se usi `Auth::attempt()` questo processo è automatico e non devi chiamarlo direttamente.
`Hash::check()` è utile quando devi verificare manualmente la password corrente.

```php theme={null}
// Esempio: verifica della password corrente in un form di cambio password
if (! Hash::check($request->current_password, $request->user()->password)) {
    return back()->withErrors(['current_password' => 'La password corrente non è corretta.']);
}
```

***

## Verifica del re-hashing

Con `Hash::needsRehash()` puoi verificare se il work factor con cui è stato generato l'hash differisce dalla configurazione attuale.
Lo usi per aggiornare gli hash esistenti alla nuova configurazione dopo aver cambiato il work factor.

```php theme={null}
use Illuminate\Support\Facades\Hash;

if (Hash::needsRehash($user->password)) {
    $user->update([
        'password' => Hash::make($plainTextPassword),
    ]);
}
```

Esempio di re-hash effettuato al successo del login.

```mermaid theme={null}
flowchart TD
    A[Login riuscito] --> B{needsRehash?}
    B -->|true| C[Rihasha con il nuovo work factor<br>e salva]
    B -->|false| D[Prosegui senza modifiche]
    C --> D
```

```php theme={null}
// Esegui il re-hash all'interno del processo di login
if (Auth::attempt($credentials)) {
    if (Hash::needsRehash(Auth::user()->password)) {
        Auth::user()->update([
            'password' => Hash::make($credentials['password']),
        ]);
    }

    return redirect()->intended('/dashboard');
}
```

<Tip>
  Rivedi periodicamente il work factor per adeguarlo al miglioramento delle prestazioni hardware, così da mantenere il livello di sicurezza. Sfruttando `needsRehash()` puoi aggiornare le password in modo naturale al momento del login degli utenti.
</Tip>

***

## Verifica dell'algoritmo di hashing

Per impostazione predefinita, `Hash::check()` verifica che l'hash sia stato generato con l'algoritmo attualmente configurato.
Se l'algoritmo è diverso viene lanciata una `RuntimeException`.

In questo modo puoi prevenire attacchi basati sulla manomissione dell'algoritmo di hashing.

Quando è necessario supportare più algoritmi contemporaneamente, ad esempio durante una migrazione, puoi disattivare questa verifica impostando `HASH_VERIFY` a `false`.

```ini theme={null}
# .env
HASH_VERIFY=false
```

<Warning>
  Con `HASH_VERIFY=false` la verifica dell'algoritmo è disattivata. Usalo solo durante il periodo di migrazione e riportalo a `true` (predefinito) al termine.
</Warning>

***

## Riepilogo

| Obiettivo                               | Metodo                             |
| --------------------------------------- | ---------------------------------- |
| Fare hashing di una password            | `Hash::make($password)`            |
| Verificare un hash                      | `Hash::check($plain, $hash)`       |
| Controllare se serve rihashing          | `Hash::needsRehash($hash)`         |
| Cambiare il driver di hashing           | Variabile d'ambiente `HASH_DRIVER` |
| Disabilitare la verifica dell'algoritmo | `HASH_VERIFY=false`                |

## Prossimi passi

<Card title="Introduzione all'autenticazione" icon="lock" href="/it/authentication">
  Impara la panoramica dell'autenticazione, inclusa l'implementazione del login usando `Hash::check()`.
</Card>


## Related topics

- [Cifratura (Encryption)](/it/encryption.md)
- [Laravel Fortify e gli starter kit](/it/advanced/fortify.md)
- [Cast personalizzati di Eloquent](/it/advanced/eloquent-casts.md)
- [Aggiornamento da Laravel 10 a 11](/it/blog/upgrade-10-to-11.md)
- [Deployment](/it/deployment.md)
