# Secure Hash Algorithm

Con il termine SHA (acronimo dell'inglese Secure Hash Algorithm) si indica una famiglia di cinque diverse funzioni crittografiche di hash sviluppate a partire dal 1993 dalla National Security Agency (NSA) e pubblicato dal NIST come standard federale dal governo degli USA (FIPS PUB 180-4).
Come ogni algoritmo di hash, l'SHA produce un message digest, o "impronta del messaggio", di lunghezza fissa partendo da un messaggio di lunghezza variabile. La sicurezza di un algoritmo di hash risiede nel fatto che la funzione non sia invertibile (non sia cioè possibile risalire al messaggio originale conoscendo solo questo dato) e che non deve essere mai possibile creare intenzionalmente due messaggi diversi con lo stesso digest. Gli algoritmi della famiglia sono denominati SHA-1, SHA-224, SHA-256, SHA-384 e SHA-512: le ultime 4 varianti sono spesso indicate genericamente come SHA-2, per distinguerle dal primo. Il primo produce un digest del messaggio di soli 160 bit, mentre gli altri producono digest di lunghezza in bit pari al numero indicato nella loro sigla (SHA-256 produce un digest di 256 bit). L'SHA-1 è il più diffuso algoritmo della famiglia SHA ed è utilizzato in numerose applicazioni e protocolli nonostante sia ormai insicuro e verrà presto sostituito dagli altri, più moderni ed efficienti.
La sicurezza di SHA-1 è stata appunto compromessa dai crittoanalisti. Sebbene non siano ancora noti attacchi alle varianti SHA-2, esse hanno un algoritmo simile a quello di SHA-1 per cui sono in atto sforzi per sviluppare algoritmi di hashing alternativi e migliorati. Un concorso aperto per la realizzazione di una nuova funzione SHA-3 venne annunciato nel Federal Register il 2 novembre 2007 dal NIST e attraverso una competizione pubblica, simile a quella adottata per il processo di sviluppo dell'AES, ha portato in data 2 ottobre 2012 ad annunciare come vincitore l'algoritmo Keccak. Opera di un team di analisti italiani e belgi, il Keccak sembra dunque destinato a venire gradualmente incluso e adottato nelle soluzioni di sicurezza informatica più variegate.
Il 23 febbraio 2017 un team di Google ha annunciato la prima tecnica pratica per generare una collisione hash.

## SHA-0 e SHA-1

La specifica originale dell'algoritmo fu pubblicata nel 1993 come Secure Hash Standard, FIPS PUB 180, dal NIST. Ci si riferisce spesso a questa versione come SHA-0 per distinguerla dalle successive versioni. Fu ritirata dall'NSA breve tempo dopo la pubblicazione e fu soppiantata da una versione rivista, pubblicata nel 1995 (FIPS PUB 180-1) e solitamente nota come SHA-1. L'SHA-1 differisce dall'SHA-0 unicamente per una sola rotazione di bit nel processo di preparazione del messaggio della sua funzione di compressione ad una via; ciò fu fatto, secondo l'NSA, per correggere un difetto nell'algoritmo originale, il quale riduceva la sicurezza crittografica di SHA-0. Ad ogni modo, l'NSA non fornì nessuna ulteriore spiegazione chiarificante. Sono state in seguito riportate debolezze sia nel codice dell'SHA-0 sia in quello dell'SHA-1. L'SHA-1 pare offrire maggiore resistenza agli attacchi, a supporto dell'asserzione dell'NSA che il cambiamento aumentò la sicurezza.
L'SHA-1 (così come l'SHA-0) produce un digest di 160 bit da un messaggio con una lunghezza massima di 2$^{64}$-1 bit, essendo fondato sulla schema di Merkel-Damgard si basa su principi simili a quelli usati da Ronald L. Rivest del MIT nel design degli algoritmi MD4 e MD5.

### Funzionamento

Passo 1 (Imbottitura): Al messaggio originale vengono aggiunti dei bit di "imbottitura" affinché la lunghezza finale del messaggio risulti congruente a 448 modulo 512, così facendo la lunghezza in bit di "messaggio+imbottitura" divisa per 512 darà resto 448.
Passo 2 (Aggiunta lunghezza): Alla sequenza di bit (messaggio+imbottitura) creata durante il passo 1 viene aggiunto un intero unsigned di 64bit contenente la lunghezza del messaggio originale. Alla fine di questi due primi passi otteniamo una sequenza di bit che è un multiplo di 512.
Passo 3 (Inizializzazione del buffer MD): Un buffer di 160bit suddiviso in 5 registri da 32bit ciascuno viene creato per la memorizzazione di alcuni passaggi intermedi. I 5 registri verranno convenzionalmente indicati con (A,B,C,D,E) ed inizializzati con i seguenti valori esadecimali:
* A = 67452301
* B = EFCDAB89
* C = 98BADCFE
* D = 10325476
* E = C3D2E1F0
Passo 4 (Elaborazione dei blocchi da 512bit): La sequenza di bit "messaggio+imbottitura+lunghezzaMessaggio" viene divisa in blocchi da 512bit, che identificheremo con B$_n$ con n che va da 0 a L. Il fulcro dell'algoritmo SHA-1 è chiamato compression function ed è formato da 4 cicli di 20 passi cadauno. I cicli hanno una struttura molto simile tra di loro se non per il fatto che utilizzano una differente funzione logica primitiva. Ogni blocco viene preso come parametro di input da tutti e 4 i cicli insieme ad una costante K e i valori dei 5 registri. Alla fine della computazione otterremo dei nuovi valori per A,B,C,D,E che useremo per la computazione del blocco successivo sino ad arrivare al blocco finale F.

## L'insieme SHA-2

Nel 2001 il NIST pubblicò quattro funzioni di hash addizionali facenti parte della famiglia SHA, ognuna con un digest più lungo di quello originale, collettivamente denominate SHA-2 (anche se questo termine non è mai stato ufficialmente standardizzato). Queste varianti sono note, come detto, con la lunghezza in bit del digest generato a seguire la sigla ufficiale dell'hash: SHA-224, SHA-256, SHA-384 e SHA-512, con, rispettivamente, hash di 224, 256, 384 e 512 bit. Da notare che gli ultimi tre algoritmi furono ufficializzati come standard nel 2002 mentre l'SHA-224 fu introdotto nel febbraio del 2004: quest'ultimo presenta un hash di lunghezza identica a quella di 2 chiavi del Triple DES.
Tutte queste varianti sono brevettate dal governo statunitense, ma pubblicate con licenza libera..
Gli algoritmi SHA-256 e SHA-512 lavorano, rispettivamente, con word di 32 e 64 bit: utilizzano un numero differente di rotazioni e di costanti addizionali, ma la loro struttura è sostanzialmente identica. Gli algoritmi SHA-224 e SHA-384 sono semplicemente versioni troncate dei precedenti due, con hash calcolati con differenti valori iniziali.
Gli algoritmi SHA-2 non hanno ricevuto, a differenza dell'SHA-1, molta attenzione dalla comunità dei crittoanalisti per cui la loro sicurezza in campo crittografico non è stata del tutto provata. Gilbert e Handschuh (2003) hanno studiato queste nuove varianti e non hanno trovato vulnerabilità.

## SHA-3

La competizione che ha portato al rilascio del nuovo standard SHA-3 è stata ufficialmente lanciata il 2 novembre 2007. Il 2 ottobre 2012 la NIST ha proclamato come vincitore l'algoritmo di Keccak SHA-3.

## Comparazione delle funzioni SHA

Nella tabella sottostante sono riportate le caratteristiche principali degli algoritmi della famiglia SHA (Per Stato interno si intende la somma interna dopo ogni compressione di un blocco di dati).
| Algoritmo e variante | Algoritmo e variante | Dimensione dell'output (bit) | Dimensione dello stato interno (bit) | Dimensione del blocco (bit) | Max. dimensione del messaggio (bit) | Dimensione della word (bit) | Passaggi | Operazioni | Collisioni trovate |
| SHA-0 | SHA-0 | 160 | 160 | 512 | 2$^{64}$ − 1 | 32 | 80 | +,and,or,xor, rotl | Sì |
| SHA-1 | SHA-1 | 160 | 160 | 512 | 2$^{64}$ − 1 | 32 | 80 | +,and,or,xor, rotl | Attacco 2$^{53}$ |
| SHA-2 | SHA-256/224 | 256/224 | 256 | 512 | 2$^{64}$ − 1 | 32 | 64 | +,and,or,xor,shr, rotr | Nessuna |
| SHA-2 | SHA-512/384 | 512/384 | 512 | 1024 | 2$^{128}$ − 1 | 64 | 80 | +,and,or,xor,shr, rotr | Nessuna |

## Applicazioni

SHA-1 è l'algoritmo più utilizzato della famiglia SHA. Costituisce la base di numerose applicazioni e protocolli, inclusi il TLS ed SSL, il PGP, l'SSH, l'S/MIME e l'IPsec. L'SHA-1 è anche utilizzato in sistemi di controllo versione, come il Git, per identificare la revisione dei software e come somma di controllo per verificare l'integrità di file di grosse dimensioni in cataloghi online.
Gli algoritmi SHA sono anche utilizzati negli algoritmi per la firma digitale dei documenti, quali ad esempio l'HMAC, e sono stati presi come base per i cifrari a blocchi SHACAL.

## Esempi e pseudocodice
### Hash di esempio

Questo è un esempio di digest generato dall'SHA-1 (tutti i messaggi sono codificati in ASCII):
Anche una minima variazione nel messaggio genera, ineluttabilmente, un hash completamente differente a causa di una reazione a catena nota come effetto valanga. Ad esempio, sostituendo Cantami con Contami otteniamo:
Il digest corrispondente alla stringa vuota è:

### Pseudocodice di SHA-1

Pseudocodice dell'algoritmo SHA-1:
Le seguenti formule possono essere utilizzate per calcolare f nel ciclo principale qui sopra pubblicato al posto di quelle originali pubblicate nel documento ufficiale FIPS PUB 180-1:

### Pseudocodice di SHA-256 (una variante di SHA-2)

Pseudocode dell'algoritmo SHA-256. Notare l'incremento nel mescolamento dei bit delle word w[16..63] rispetto all'SHA-1.
Le funzioni ch e maj possono essere ottimizzate nel modo descritto per quelle dell'SHA-1.
L'SHA-224 è identico all'SHA-256 tranne che:
* i valori iniziali delle variabili h0-h7 sono differenti e
* l'output è costruito omettendo h7.
L'SHA-512 è identico nella struttura ma:
* tutti i numeri sono lunghi 64 bit,
* sono eseguiti 80 passaggi invece di 64,
* i valori iniziali e le costanti da addizionare sono estesi a 64 bit e
* le quantità delle rotazioni (rotate) e degli spostamenti (shift) sono differenti.
L'SHA-384 è identico all'SHA-512 tranne che:
* i valori iniziali h0-h7 sono differenti e
* l'output è costruito omettendo h6 e h7.