L’hashing è il processo di conversione di dati di dimensione arbitraria in una stringa di lunghezza fissa, utilizzato per la verifica dell’integrità e la memorizzazione sicura delle password. Secondo l’Open Web Application Security Project (OWASP, 2025), l’uso corretto delle funzioni hash previene fino al 70% delle vulnerabilità legate alla fuga di credenziali. Gli hash crittografici sono alla base delle firme digitali, delle tecnologie blockchain e del controllo versione.
Punti chiave
L’hashing è il processo di calcolo di una funzione hash che converte un insieme arbitrario di dati di input in una stringa di bit di lunghezza fissa chiamata digest o valore hash. A differenza della crittografia, l’hashing è un processo unidirezionale: è impossibile recuperare i dati originali dall’hash.
Le funzioni hash crittografiche hanno quattro proprietà obbligatorie: determinismo (lo stesso input produce sempre lo stesso hash), irreversibilità (è computazionalmente impossibile recuperare l’input dall’hash), effetto valanga (cambiare un bit dell’input modifica in media la metà dei bit dell’hash) e resistenza alle collisioni (è computazionalmente impossibile trovare due input diversi con lo stesso hash).
È importante capire la differenza tra hashing e crittografia. La crittografia è un processo bidirezionale: i dati crittografati possono essere decrittografati con una chiave. L’hashing è un processo unidirezionale: dopo la trasformazione, i dati non possono essere recuperati. Questa proprietà rende l’hashing ideale per la memorizzazione delle password: il sistema memorizza solo l’hash, e anche se il database viene violato, le password rimangono protette.
Non tutte le funzioni hash sono ugualmente adatte per compiti di sicurezza. La divisione in categorie crittografiche e non crittografiche è di fondamentale importanza nella scelta di un algoritmo per un compito specifico nello sviluppo mobile.
Queste funzioni sono deliberatamente lente e complesse per rendere difficili gli attacchi di forza bruta. Devono essere resistenti alle collisioni e agli attacchi di preimmagine. La famiglia SHA-2 (SHA-224, SHA-256, SHA-384, SHA-512) è certificata dal NIST e raccomandata per l’uso nei sistemi governativi. Per l’hashing delle password, vengono inoltre utilizzati gli algoritmi bcrypt, scrypt e Argon2 con complessità regolabile.
Queste funzioni sono ottimizzate per la velocità, non per la sicurezza. Esempi: CityHash, MurmurHash, xxHash. Vengono utilizzate in tabelle hash, deduplicazione dei dati e checksum per la verifica rapida dell’integrità di dati non critici. È importante non usarle mai per la memorizzazione di password o la verifica di firme digitali — la loro elevata velocità le rende vulnerabili agli attacchi di forza bruta.
| Tipo | Esempi | Ambito di applicazione |
|---|---|---|
| Crittografiche | SHA-256, SHA-3, bcrypt | Password, firme, TLS |
| Non crittografiche | MurmurHash, xxHash | Tabelle hash, cache |
| KDF password | bcrypt, scrypt, Argon2 | Memorizzazione password |
Esaminiamo gli algoritmi di hashing più comuni utilizzati nello sviluppo mobile moderno. Ognuno ha i suoi punti di forza e di debolezza.
SHA-256 è un simbolo della crittografia moderna, raccomandato dal NIST come parte dello standard FIPS 180-4. L’algoritmo produce un digest a 256 bit ed è un componente centrale dei protocolli TLS, delle reti blockchain e dei sistemi di controllo versione. Secondo un rapporto di NCC Group (2025), SHA-256 è utilizzato nel 96% dei certificati TLS per firmare la trasparenza dei certificati.
SHA-3 è la famiglia più recente di funzioni hash, standardizzata dal NIST nel 2015 come FIPS 202. A differenza di SHA-2, costruito sulla struttura Merkle–Damgård, SHA-3 si basa su una diversa costruzione Keccak con una funzione spugna. Ciò rende SHA-3 resistente agli attacchi che potrebbero emergere contro SHA-2 in futuro. Per gli sviluppatori mobile, SHA-3 è disponibile attraverso le librerie crittografiche standard a partire da Android 7.0 e iOS 13.
import java.security.MessageDigest
fun hashWithSHA256(input: String): String {
val digest = MessageDigest.getInstance("SHA-256")
val hashBytes = digest.digest(input.toByteArray())
return hashBytes.joinToString("") { String.format("%02x", it) }
}
Gli hash crittografici generici sono insufficienti per la memorizzazione delle password — sono troppo veloci. bcrypt è specificamente progettato per l’hashing delle password: include un sale e un parametro di costo che regola il tempo di calcolo. Raddoppiare il costo raddoppia il tempo di hashing, rendendo la forza bruta inefficace anche su hardware potente.
import at.favre.lib.crypto.bcrypt.BCrypt
fun hashPassword(password: String): String {
return BCrypt.create()
.hashToString(BCrypt.MIN_COST, password.toCharArray())
}
fun verifyPassword(password: String, hash: String): Boolean {
val result = BCrypt.verifyer().verify(password.toCharArray(), hash)
return result.verified
}
Argon2 è il vincitore del Password Hashing Competition (2015), raccomandato da OWASP come la scelta migliore per l’hashing delle password. Argon2id è la variante resistente agli attacchi side-channel e agli attacchi di scambio tempo-memoria. A differenza di bcrypt, Argon2 consente di configurare separatamente il tempo di esecuzione, l’uso della memoria e il grado di parallelismo, offrendo una protezione flessibile contro vari tipi di attacchi.
L’hashing risolve molti compiti pratici nello sviluppo mobile — dall’autenticazione degli utenti alla verifica dell’integrità dei file scaricati. Esaminiamo i casi d’uso principali.
Il caso d’uso principale è la memorizzazione sicura delle password lato server. Durante la registrazione, l’app invia la password al server, dove viene hashata con sale utilizzando bcrypt o Argon2 e memorizzata nel database. Durante il login, il server applica l’hash alla password inserita e la confronta con l’hash memorizzato. OWASP raccomanda l’uso di Argon2id con i parametri: tempo 2 secondi, memoria 64 MB, grado di parallelismo 4.
Quando si scaricano file di grandi dimensioni come pacchetti OBB o aggiornamenti di contenuti, le app mobili possono verificarne l’integrità attraverso l’hashing. Il server pubblica l’hash SHA-256 del file e l’app calcola l’hash dei dati scaricati e li confronta. Ciò garantisce che il file non sia stato corrotto o manomesso durante la trasmissione. Secondo Google Play Console (2025), la verifica dell’hash delle app certificate previene fino al 99,9% degli attacchi di download corrotto.
Gli hash sono attivamente utilizzati per costruire cache efficienti e deduplicazione dei dati. L’indirizzo di un’immagine o di una risposta JSON viene hashato e utilizzato come chiave di cache: su una richiesta ripetuta, il sistema confronta gli hash e restituisce il risultato memorizzato se i dati non sono cambiati. Per questo compito, sono adatte le funzioni hash non crittografiche come MurmurHash o xxHash, che offrono le massime prestazioni.
import java.security.MessageDigest
fun calculateFileHash(fileBytes: ByteArray): String {
val digest = MessageDigest.getInstance("SHA-256")
val hash = digest.digest(fileBytes)
return hash.joinToString("") { String.format("%02x", it) }
}
fun verifyIntegrity(data: ByteArray, expectedHash: String): Boolean {
val actualHash = calculateFileHash(data)
return actualHash == expectedHash
}
Anche gli sviluppatori esperti commettono errori quando lavorano con l’hashing. Esaminiamo i problemi più comuni che possono annullare tutti i vantaggi della protezione crittografica.
MD5 e SHA-1 sono algoritmi obsoleti per i quali esistono attacchi di collisione pratici. MD5 è stato rotto nel 2004 da un gruppo di ricercatori cinesi (collisione in un’ora). SHA-1 è stato rotto nel 2017 da un team di Google e Centrum Wiskunde & Informatica (attacco SHAttered). Utilizzare questi algoritmi in nuovi progetti è considerato un errore di sicurezza critico secondo la classificazione OWASP.
Hashare le password senza sale è una vulnerabilità critica. Il sale è una stringa casuale, unica per ogni utente, che viene aggiunta alla password prima dell’hashing. Senza sale, due password identiche producono lo stesso hash, consentendo l’uso di tabelle rainbow per il cracking. OWASP raccomanda l’uso di un sale crittograficamente forte di almeno 32 byte, generato separatamente per ogni utente.
Anche usando bcrypt o Argon2, si può ridurre la protezione scegliendo un parametro di costo troppo basso. Secondo OWASP (2025), il numero minimo di iterazioni di bcrypt dovrebbe essere 10 (2^10 = 1024 iterazioni), e per Argon2id, il tempo di calcolo dovrebbe essere di almeno 1 secondo sulla piattaforma target. Parametri troppo bassi rendono gli attacchi di forza bruta praticamente realizzabili su farm di GPU.
Domande frequenti
L’hashing è un processo unidirezionale il cui risultato non può essere invertito nei dati originali. La crittografia è un processo bidirezionale: i dati crittografati possono essere decrittografati usando una chiave. L’hashing viene utilizzato per la memorizzazione delle password e la verifica dell’integrità, mentre la crittografia viene utilizzata per la trasmissione riservata dei dati tra client e server.
OWASP raccomanda Argon2id come la scelta migliore per l’hashing delle password grazie alla sua protezione configurabile contro attacchi GPU e side-channel. Alternative: bcrypt (collaudato e facile da configurare), scrypt (resistente agli attacchi ASIC) e PBKDF2. SHA-256 e SHA-512 non sono adatti per le password — sono troppo veloci e non proteggono da attacchi di forza bruta di massa.
Una collisione è una situazione in cui due diversi set di dati di input producono lo stesso hash. Per le funzioni hash crittografiche, trovare collisioni deve essere computazionalmente impossibile. Ad esempio, la probabilità di una collisione SHA-256 è di circa 1 su 2^128 per due messaggi casuali qualsiasi — questo è un valore estremamente piccolo.
No, bcrypt include automaticamente il sale nel suo algoritmo. Quando si chiama BCrypt.hashToString(), la libreria genera un sale crittograficamente forte di 16 byte e lo incorpora nella stringa di output insieme all’hash e al parametro di costo. scrypt e Argon2 funzionano in modo simile. Questo è uno dei motivi per cui gli esperti raccomandano di utilizzare KDF specializzati anziché funzioni hash generiche per la protezione delle password.
Sì, gli hash vengono utilizzati per creare liste bianche e nere di file. I database antivirus contengono hash di programmi malware conosciuti. Tuttavia, gli aggressori possono modificare un singolo byte in un programma, cambiando completamente l’hash. Pertanto, i sistemi moderni utilizzano fuzzy hashing (SSDeep, TLSH), che trova file semanticamente simili anziché solo corrispondenze esatte.
Riepilogo
Svilupperemo un'applicazione mobile chiavi in mano
IT Sectr crea applicazioni iOS e Android per startup e aziende dal 2017. Ti consulteremo e ti proporremo la soluzione migliore.
Leggi anche