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

# Cifratura (Encryption)

> Come cifrare e decifrare valori con la facade Crypt di Laravel usando AES-256-CBC. Copre la generazione di APP_KEY, i cast dei modelli e il salvataggio sicuro di dati personali.

## Cos'è la facade Crypt

Il servizio di cifratura di Laravel offre una semplice interfaccia per cifrare e decifrare valori usando la cifratura **OpenSSL** AES-256-CBC (o AES-128-CBC).

Tutti i valori cifrati con Laravel sono firmati con un **Message Authentication Code (MAC)**.
Se il valore cifrato viene manomesso, non è più possibile decifrarlo.

```mermaid theme={null}
flowchart LR
    A["Dati in chiaro"] -->|"Crypt::encryptString()"| B["Valore cifrato<br>(firmato con MAC)"]
    B -->|"Crypt::decryptString()"| A
    B -->|Rilevata manomissione| C["DecryptException"]
```

***

## Configurazione

### Generare APP\_KEY

Prima di usare la cifratura è necessaria la configurazione `key` di `config/app.php`.
Questo valore viene letto dalla variabile d'ambiente `APP_KEY`.

Usa il comando `php artisan key:generate` per generare una chiave sicura.
Viene generata una chiave crittograficamente sicura usando il generatore di numeri casuali sicuro di PHP.

```shell theme={null}
php artisan key:generate
```

Di norma viene generata automaticamente durante l'installazione di Laravel. La chiave generata viene salvata nel file `.env`.

```ini theme={null}
APP_KEY=base64:J63qRTDLub5NuZvP+kb8YIorGS6qFYHKVo6u7179stY=
```

<Warning>
  Non divulgare mai `APP_KEY`. Se venisse compromessa, tutti i dati cifrati sarebbero decifrabili.
</Warning>

### Rotazione delle chiavi di cifratura

Cambiando la chiave di cifratura, tutte le sessioni utente autenticate vengono terminate.
Questo perché Laravel cifra tutti i cookie, inclusi i cookie di sessione.

Inoltre, i dati cifrati con la chiave precedente non potranno più essere decifrati.

Per mitigare il problema, puoi elencare le chiavi precedenti in `APP_PREVIOUS_KEYS`, separate da virgola.

```ini theme={null}
APP_KEY="base64:J63qRTDLub5NuZvP+kb8YIorGS6qFYHKVo6u7179stY="
APP_PREVIOUS_KEYS="base64:2nLsGFGzyoae2ax3EF2Lyq/hH6QghBGLIq5uL+Gp8/w="
```

Laravel usa sempre la chiave corrente per cifrare. In fase di decifratura, se la chiave corrente fallisce, prova in ordine quelle precedenti.
In questo modo gli utenti possono continuare a usare l'applicazione durante la rotazione delle chiavi.

***

## Cifratura

Usa il metodo `encryptString` della facade `Crypt` per cifrare un valore.
Il valore cifrato usa OpenSSL con cifratura AES-256-CBC e viene firmato con un MAC.

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

namespace App\Http\Controllers;

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

class DigitalOceanTokenController extends Controller
{
    /**
     * Salva il token API dell'utente
     */
    public function store(Request $request): RedirectResponse
    {
        $request->user()->fill([
            'token' => Crypt::encryptString($request->token),
        ])->save();

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

<Tip>
  `encryptString` cifra la stringa **senza** serializzazione. Per cifrare oggetti o array usa `encrypt`.
</Tip>

| Metodo                         | Uso                                                          |
| ------------------------------ | ------------------------------------------------------------ |
| `Crypt::encryptString($value)` | Cifra la stringa così com'è                                  |
| `Crypt::encrypt($value)`       | Serializza il valore e poi lo cifra (supporta array/oggetti) |

***

## Decifratura

Con il metodo `decryptString` della facade `Crypt` decifri un valore.
Se la decifratura non riesce (ad esempio MAC non valido) viene lanciata `DecryptException`.

```php theme={null}
use Illuminate\Contracts\Encryption\DecryptException;
use Illuminate\Support\Facades\Crypt;

try {
    $decrypted = Crypt::decryptString($encryptedValue);
} catch (DecryptException $e) {
    // Gestione del fallimento della decifratura
    abort(400, 'Dati non validi.');
}
```

| Metodo                         | Uso                                             |
| ------------------------------ | ----------------------------------------------- |
| `Crypt::decryptString($value)` | Decifra come stringa                            |
| `Crypt::decrypt($value)`       | Decifra e deserializza (supporta array/oggetti) |

***

## Cast dei modelli

Nei modelli Eloquent puoi cifrare e decifrare attributi automaticamente con il cast `encrypted`.

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

namespace App\Models;

use Illuminate\Database\Eloquent\Model;

class User extends Model
{
    protected function casts(): array
    {
        return [
            'secret_note'    => 'encrypted',           // Cifratura di una stringa
            'profile_data'   => 'encrypted:array',     // Salva un array cifrato
            'preferences'    => 'encrypted:collection',// Salva una collection cifrata
            'metadata'       => 'encrypted:object',    // Salva un oggetto cifrato
            'settings'       => 'encrypted:json',      // Salva JSON cifrato
        ];
    }
}
```

Con il cast configurato, gli attributi vengono cifrati/decifrati automaticamente al momento dell'assegnazione o della lettura.

```php theme={null}
// Cifrato automaticamente e salvato nel DB
$user->secret_note = 'Nota segreta';
$user->save();

// Decifrato automaticamente in lettura
echo $user->secret_note; // 'Nota segreta'
```

<Info>
  I cast `encrypted:*` usano internamente `Crypt::encrypt` e `Crypt::decrypt`.
  Per la colonna del database sono consigliati i tipi `text` o `longText`.
</Info>

***

## Esempio pratico: salvataggio cifrato di dati personali

Pattern tipico per salvare in modo sicuro dati personali (codice fiscale, numero di carta di credito, ecc.) nel database.

### Migration

```php theme={null}
Schema::create('profiles', function (Blueprint $table) {
    $table->id();
    $table->foreignId('user_id')->constrained();
    $table->text('tax_code')->nullable();      // Valore cifrato salvato come text
    $table->text('bank_account')->nullable();
    $table->timestamps();
});
```

### Modello

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

namespace App\Models;

use Illuminate\Database\Eloquent\Model;

class Profile extends Model
{
    protected $fillable = ['user_id', 'tax_code', 'bank_account'];

    protected function casts(): array
    {
        return [
            'tax_code'     => 'encrypted',
            'bank_account' => 'encrypted',
        ];
    }
}
```

### Controller

```php theme={null}
use App\Models\Profile;
use Illuminate\Http\Request;

class ProfileController extends Controller
{
    public function store(Request $request)
    {
        $request->validate([
            'tax_code'     => ['required', 'string'],
            'bank_account' => ['required', 'string'],
        ]);

        // Il modello cifra e salva automaticamente
        Profile::create([
            'user_id'      => $request->user()->id,
            'tax_code'     => $request->tax_code,
            'bank_account' => $request->bank_account,
        ]);

        return redirect('/profile');
    }

    public function show(Request $request)
    {
        $profile = $request->user()->profile;

        // Il modello decifra automaticamente in lettura
        return view('profile.show', ['profile' => $profile]);
    }
}
```

***

## Riepilogo

| Obiettivo                                        | Metodo                                             |
| ------------------------------------------------ | -------------------------------------------------- |
| Generare APP\_KEY                                | `php artisan key:generate`                         |
| Cifrare una stringa                              | `Crypt::encryptString($value)`                     |
| Decifrare una stringa                            | `Crypt::decryptString($value)`                     |
| Cifrare array/oggetti                            | `Crypt::encrypt($value)`                           |
| Cifrare automaticamente un attributo del modello | Cast `'column' => 'encrypted'`                     |
| Rotazione delle chiavi                           | Elenca le chiavi precedenti in `APP_PREVIOUS_KEYS` |

## Prossimi passi

<Columns cols={2}>
  <Card title="Hashing" icon="lock" href="/it/hashing">
    Impara come fare hashing sicuro delle password e come verificarle.
  </Card>

  <Card title="Autorizzazione" icon="shield" href="/it/authorization">
    Il controllo degli accessi con Policy e Gate.
  </Card>
</Columns>


## Related topics

- [Autenticazione OAuth 2.0 - Google Sheets API for Laravel](/it/packages/laravel-google-sheets/oauth.md)
- [Configurazione](/it/configuration.md)
- [Routing](/it/routing.md)
- [Deployment](/it/deployment.md)
- [Struttura delle directory](/it/directory-structure.md)
