Cos'è hashing?

Hashing: Un'Introduzione

L'hashing è un processo che trasforma un input di dati, di qualsiasi dimensione, in un output di dimensione fissa, chiamato hash o hash code. L'hash code è un valore univoco (idealmente) che rappresenta l'input originale. L'hashing è ampiamente utilizzato in informatica per una varietà di scopi, tra cui:

  • Tabelle Hash: L'hashing è fondamentale per l'implementazione di efficienti tabelle hash, strutture dati che permettono l'accesso, l'inserimento e la cancellazione di elementi in tempo (idealmente) costante.
  • Verifica dell'Integrità dei Dati: Calcolando l'hash di un file, si può verificare se il file è stato alterato confrontando l'hash calcolato con un hash precedentemente memorizzato. Questo è spesso utilizzato per la verifica del download di software o la rilevazione di alterazioni in file di sistema.
  • Archiviazione delle Password: Le password non dovrebbero mai essere memorizzate in chiaro. Invece, vengono sottoposte a hashing e l'hash viene memorizzato. Quando un utente tenta di effettuare il login, la password inserita viene hashata e confrontata con l'hash memorizzato. Questo metodo protegge le password nel caso di una violazione della sicurezza, poichè l'hash è (idealmente) irreversibile. Solitamente, le password hashate sono anche "salate" (salt) per aumentare la sicurezza. Salt è un valore casuale aggiunto alla password prima dell'hashing per prevenire attacchi "rainbow table".
  • Indicizzazione di Dati: L'hashing può essere utilizzato per creare indici rapidi per grandi dataset, consentendo ricerche più efficienti.
  • Crittografia: Anche se l'hashing non è crittografia in sé (perchè idealmente non invertibile), è spesso utilizzato come componente in molti algoritmi crittografici. Esempi includono l'uso di funzioni hash per generare chiavi crittografiche o per creare firme digitali.

Funzioni Hash:

Una funzione hash è l'algoritmo matematico che esegue il processo di hashing. Una buona funzione hash deve avere le seguenti caratteristiche:

  • Determinismo: Lo stesso input deve sempre produrre lo stesso output (hash).
  • Uniformità: L'hash deve distribuire uniformemente i valori di input nello spazio di output, minimizzando le collisioni.
  • Efficienza: Il calcolo dell'hash deve essere computazionalmente efficiente.
  • Resistenza alla preimmagine (preimage resistance): Dato un valore hash h, dovrebbe essere computazionalmente infattibile trovare un input m tale che hash(m) = h. Questo è anche noto come proprietà di "one-way".
  • Resistenza alla seconda preimmagine (second preimage resistance): Dato un input m1, dovrebbe essere computazionalmente infattibile trovare un altro input m2 (diverso da m1) tale che hash(m1) = hash(m2).
  • Resistenza alle collisioni (collision resistance): Dovrebbe essere computazionalmente infattibile trovare due input diversi m1 e m2 tali che hash(m1) = hash(m2).

Tipologie di Funzioni Hash:

Esistono diverse tipologie di funzioni hash, ognuna con i suoi punti di forza e di debolezza:

  • Funzioni Hash Crittografiche: Progettate per essere resistenti alle collisioni e alla preimmagine, usate in sicurezza. Esempi comuni includono SHA-256, SHA-3, e MD5 (sebbene MD5 non sia più considerato sicuro a causa di vulnerabilità note).
  • Funzioni Hash Non Crittografiche: Progettate per velocità e efficienza, adatte per tabelle hash e altre applicazioni dove la sicurezza non è una preoccupazione primaria. Esempi includono MurmurHash e xxHash.

Considerazioni Importanti:

  • Collisioni: Poiché l'hash ha una dimensione fissa, è inevitabile che input diversi possano produrre lo stesso hash. Questo è noto come collisione. Una buona funzione hash minimizza il numero di collisioni, ma è necessario implementare meccanismi di gestione delle collisioni (ad esempio, chaining o probing) nelle applicazioni che utilizzano l'hashing.
  • Sicurezza: Non tutte le funzioni hash sono adatte per applicazioni che richiedono sicurezza. È fondamentale scegliere una funzione hash appropriata in base alle esigenze di sicurezza dell'applicazione.
  • Lunghezza dell'Hash: La lunghezza dell'hash influisce sulla probabilità di collisioni e sulla sicurezza. Hash più lunghi offrono una maggiore sicurezza, ma richiedono più spazio di archiviazione.