Funzioni HASH

Una funzione di hash è una funzione matematica che mappa dati di dimensione arbitraria in dati di dimensione fissa. Questo processo è deterministico, ovvero per lo stesso input la funzione di hash restituirà sempre lo stesso output. Le funzioni di hash sono utilizzate in crittografia in diversi contesti, tra cui:

  • Integrità dei dati: per verificare che un messaggio non sia stato alterato durante la trasmissione. Per esempio, un hash può essere calcolato su un messaggio e inviato insieme al messaggio. Il destinatario può quindi calcolare l'hash sul messaggio ricevuto e confrontarlo con l'hash ricevuto per verificare l'integrità del messaggio.
  • Firma digitale: per generare firme digitali. Una firma digitale è un hash di un messaggio cifrato con la chiave privata del mittente. Il destinatario può verificare la firma decifrando il messaggio con la chiave pubblica del mittente e confrontando l'hash del messaggio con l'hash decifrato. Questo garantisce che il messaggio sia stato firmato dal mittente e non sia stato alterato.
  • Password hashing: per proteggere le password degli utenti. Le password non vengono memorizzate direttamente nel database, ma viene invece calcolato l'hash prima di essere memorizzate. Quando un utente accede, viene calcolato l'hash della password inserita e confrontata con l'hash memorizzato nel database. Questo protegge le password in caso di violazione del database.

Le funzioni di hash sono progettate per essere veloci da calcolare, ma difficili da invertire. Questo significa che, dato un hash, è computazionalmente difficile trovare l'input corrispondente. Inoltre, funzioni di hash diverse dovrebbero produrre output diversi anche per input simili.

Alcune proprietà desiderabili di una funzione di hash includono:

  • Deterministicità: per lo stesso input, la funzione di hash restituirà sempre lo stesso output.
  • Rapidezza: le funzioni di hash devono essere veloci da calcolare.
  • Difficoltà di inversione: è computazionalmente difficile trovare l'input corrispondente a un hash.
  • Diffusione: piccole modifiche all'input dovrebbero produrre output completamente diversi. Questo rende difficile prevedere l'output di una funzione di hash per input simili.
  • Collisione: è computazionalmente difficile trovare due input diversi che producono lo stesso hash. Perché se fosse facile trovare due input diversi che producono lo stesso hash, un attaccante potrebbe modificare un messaggio firmato senza che il destinatario se ne accorga.

Per funzioni di hash le proprietà crittografiche sono:

  • Dato un hash a n bit, la probabilità che un messaggio random produca lo stesso hash è \(1/2^n\).
  • Resistenza alla preimmagine: è computazionalmente difficile trovare un input che produce un hash specifico, cioè dato \(h\) è difficile trovare \(m\) tale che \(h = H(m)\). Dovrebbe richiedere un tempo proporzionale a \(2^n\) per una funzione di hash a n bit.
  • Resistenza alla seconda preimmagine: è computazionalmente difficile trovare un secondo input che produce lo stesso hash di un input specifico, cioè dato \(m_1\) è difficile trovare \(m_2\) tale che \(H(m_1) = H(m_2)\).
  • Resistenza alle collisioni: è computazionalmente difficile trovare due input diversi che producono lo stesso hash, cioè è difficile trovare \(m_1\) e \(m_2\) tali che \(H(m_1) = H(m_2)\). La difficoltà dovrebbe essere proporzionale a \(2^{n/2}\) per una funzione di hash a n bit.

Le funzioni di hash più comuni includono MD5, SHA-1 e SHA-256. Tuttavia, MD5 e SHA-1 sono considerate ormai obsolete e vulnerabili ad attacchi collisioni. In particolare MD5 permette collisioni in pochi secondi su un normale computer, mentre SHA-1 permette collisioni ma a costi molto più elevati. SHA-256 è una funzione di hash più sicura e resistente, che produce un hash di 256 bit. La funzione SHA-256 è attualmente considerata sicura e viene utilizzata in molte applicazioni crittografiche.