Derivazione di una chiave crittografica
# Derivazione di una chiave crittografica

Derivare una chiave crittografica significa ricavare una o più chiavi crittografiche da una chiave principale (in inglese detta solitamente master key) o da altra informazione disponibile, ad esempio una password o una passphrase. Ciò viene fatto in base ad una opportuna funzione di derivazione della chiave (in inglese Key derivation function o KDF) che ricava la chiave derivata a partire da dati noti. Una diffusa applicazione della derivazione di una chiave è in HMAC.

Un algoritmo di derivazione della chiave (v. ad esempio PBKDF2), a partire da un valore arbitrario in ingresso (una stringa o un array di grandi dimensioni) calcola in modo crittograficamente sicuro (ovvero non è possibile abbreviare il calcolo con una qualche scorciatoia) una chiave di dimensioni adatte alla cifratura. Questo fa sì che sia possibile imporre un dato tempo di calcolo per generare una chiave, nota la password (o una qualsivoglia informazione segreta), in modo che un attaccante che provi un attacco a forza bruta o anche solo un attacco a dizionario si trovi rallentato (in modo non bypassabile) nelle operazioni. Unendo alla password un valore pseudocasuale, che non ha bisogno di restare segreto (seed o salt), in ingresso alla funzione di derivazione della password si fa in modo che l'avversario non possa nemmeno precalcolare le chiavi corrispondenti alle password più probabili, perché saranno diverse al cambiare del salt, e quindi diverse per ogni file cifrato.

## Usi della derivazione di chiave

* Le funzioni di derivazione di chiave sono funzioni di hash crittografiche, spesso usate in congiunzione con parametri non segreti per derivare una o più chiavi da una stessa informazione segreta. Un suo utilizzo può evitare che un attaccante che entri in possesso della chiave derivata apprenda informazioni sensibili sul valore segreto effettivamente in input. Una KDF può anche essere usata per assicurare che le chiavi derivate abbiano altre proprietà desiderabili, come ad esempio evitare chiavi deboli in alcuni specifici sistemi di crittografia.
* Le funzioni di derivazione di chiavi sono spesso usate come componenti di protocolli di key-agreement tra più parti. Esempi di alcune funzioni di derivazione di chiavi includono KDF1, definito nello IEEE P1363, e funzioni simili in ANSI X9.42.
* Funzioni di derivazione delle chiavi sono usate anche per derivare delle chiavi da una password segreta o una passphrase.

### Funzioni di derivazione di chiave basate su password

Le funzioni di derivazione di chiave sono usate anche nelle applicazioni per derivare chiavi da password segrete oppure passphrase, le quali tipicamente non possono essere usate direttamente come chiavi crittografiche. In certe applicazioni, è generalmente raccomandato che la funzione di derivazione della chiave generi lentamente la chiave derivata, in modo da scoraggiare gli attacchi a forza bruta o a dizionario sulla password o sulla passphrase in input.

Un particolare uso di una funzione di derivazione di chiave può essere il seguente:

$DK=KDF(Key,Salt,Iterations)$

dove:

* $DK$ è la chiave derivata
* $KDF$ è la funzione di derivazione di chiave
* $Key$ è la chiave originale o la password
* $Salt$ è un valore casuale che svolge il ruolo di salt crittografico
* $Iterations$ si riferisce al numero di iterazioni della funzione

La chiave derivata è usata al posto della chiave originale o della password, come chiave del sistema. Il valore del salt e il numero di iterazioni (se non è prefissato) sono memorizzati nel valore hash della password o inviati come testo in chiaro insieme al messaggio criptato.

La difficoltà di forzare la chiave con un attacco a forza bruta aumenta all'aumentare del numero di iterazioni. Un limite pratico sul numero di iterazioni è la riluttanza degli utenti a tollerare un ritardo percepibile nell'effettuare il login nel sistema o nel vedere il messaggio decifrato. L'uso di un salt crittografico impedisce, come detto prima, di precalcolare un dizionario di chiavi derivate.

La prima funzione di derivazione di chiave basata su password, deliberatamente lenta dal punto di vista computazionale, fu chiamata "crypt" ("crypt(3)" nelle pagine di manuale di Unix) e fu inventata da Robert Morris nel 1980 per cifrare le password Unix. Tuttavia in quel periodo si verificava anche un aumento della velocità dei processori, che rendeva fattibile un attacco di brute force contro crypt, inoltre l'aumento della capacità delle memorie rendeva inadeguato un salt a 12 bit. La funzione crypt limitava anche la password utente a 8 caratteri, limitando così anche la dimensione dello spazio delle chiavi e impedendo la definizione di passphrase "forti".

Le moderne funzioni di derivazione di chiave basate su password, come PBKDF2 (specificata nel RFC 2898) utilizzano una funzione di hash crittografica, come MD5 o SHA1, salt molto grandi (ad esempio su 64 bit) e un grande valore di iterazione (spesso 1000 o più). Ci sono state proposte per utilizzare algoritmi che richiedessero memorie molto grandi e altre risorse di calcolo, in modo da ostacolare attacchi custom hardware.

