Il Divario tra Usare Qualcosa e Capirla
All'inizio della mia carriera stavo analizzando un problema di autenticazione quando un collega senior mi chiese: "Il JWT è scaduto?"
Dissi di sì, l'avevo controllato. Quello che non ammisi: avevo incollato il token su un sito a caso, visto il timestamp di scadenza, e non ero ancora del tutto sicuro di cosa stessi guardando. Era sicuro? Chiunque poteva leggere quel token? Era criptato? Perché qualsiasi sito poteva decodificarlo se era "firmato" e "sicuro"?
Questa guida è per quella versione di me. Tre concetti che compaiono costantemente nello sviluppo web, che la maggior parte dei tutorial presuppone già noti, e che sono in realtà semplici una volta spiegati chiaramente.
Base64: Non è Cifratura. Non è Compressione. È Solo Traduzione.
La cosa più importante da sapere: Base64 non è un meccanismo di sicurezza. Non nasconde i tuoi dati. Chiunque può decodificarlo istantaneamente. Se hai mai pensato "questo sembra codificato quindi è probabilmente sicuro da mettere in un URL" — non lo è.
Base64 è un modo per rappresentare dati binari usando solo caratteri ASCII stampabili. Questo è tutto il punto. Il motivo pratico per cui esiste: i dati binari rompono le cose. Email, header HTTP, URL, attributi HTML — questi sistemi sono stati costruiti per il testo. I dati binari grezzi, con i loro null byte e caratteri di controllo, possono corrompersi passando attraverso sistemi basati su testo.
Base64 converte il binario in un alfabeto sicuro di 64 caratteri: A–Z, a–z, 0–9, + e /. L'output è circa il 33% più grande dell'input ma garantito di viaggiare intatto attraverso qualsiasi sistema basato su testo.
Dove lo vedrai davvero
HTTP Basic Authentication: Quando ti autentichi con username:password, le credenziali vengono codificate in Base64 e inviate nell'header Authorization: Basic. Ecco perché Basic Auth su HTTP semplice è pericoloso — chiunque intercetti la richiesta può decodificare le credenziali immediatamente. HTTPS è obbligatorio.
Token JWT: Ciascuna delle tre sezioni di un JWT è codificata in Base64url (una variante che sostituisce + e / con - e _ per essere sicura negli URL).
Data URI: <img src="data:image/png;base64,iVBORw0KGgo..."> — incorporare dati immagine direttamente in HTML o CSS invece di fare una richiesta HTTP separata.
Allegati email: La codifica MIME usa Base64 affinché i file binari possano viaggiare attraverso server di posta progettati solo per testo.
Prova tu stesso: incolla qualsiasi testo nel Codificatore Base64 e guarda l'output. Poi incolla la stringa codificata e decodificala. Nota che la versione codificata non nasconde nulla — usa semplicemente un alfabeto diverso.
JWT: Tre Stringhe Base64 e una Firma
Un JSON Web Token assomiglia a questo:
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VySWQiOiIxMjMiLCJlbWFpbCI6InVzZXJAZXhhbXBsZS5jb20iLCJleHAiOjE3MTM5MzYwMDB9.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c
Esattamente due punti. Tre sezioni.
Header — la parte prima del primo punto. Si decodifica in metadati sul token: quale algoritmo di firma è stato usato, che tipo di token è.
Payload — la sezione centrale. Si decodifica nelle claims effettive: ID utente, email, ruoli, tempo di scadenza. Questo è ciò che il tuo backend legge per identificare l'utente.
Firma — la parte dopo il secondo punto. Una prova crittografica che il token non è stato manomesso.
La cosa che sorprende la maggior parte degli sviluppatori
Il payload è codificato in Base64url. Non è criptato. Chiunque abbia il token può decodificare il payload e leggerne i contenuti — ID utente, email, ruoli, scadenza, qualunque cosa ci hai messo.
Incolla qualsiasi JWT nel Decodificatore JWT e vedi esattamente cosa contiene. Nessuna chiave richiesta.
Questo sorprende le persone perché la stringa sembra opaca e incomprensibile. Non lo è. Il modello di sicurezza del JWT è: "Posso verificare che questo token sia stato genuinamente emesso dal mio server (controllo della firma), quindi posso fidarmi delle claims che contiene. Ma quelle claims stesse non sono segrete."
L'implicazione pratica: non mettere password, dati di pagamento o informazioni personali sensibili nei payload JWT. Includi solo ciò che è necessario per identificare e autorizzare l'utente. ID utente, livello del piano e ruoli vanno benissimo.
Cosa fa davvero la firma
La firma viene creata prendendo header + payload + una chiave segreta che solo il tuo server conosce, e passandoli attraverso una funzione hash. Quando il tuo server riceve un token, ricalcola la firma usando lo stesso segreto. Se la firma ricalcolata corrisponde alla firma del token, il token è autentico e invariato.
Se qualcuno modifica il payload per cambiare l'ID utente 123 in 456 (per impersonare un altro utente), il controllo della firma fallisce — il payload modificato produce una firma diversa da quella nel token.
Ecco perché il segreto di firma JWT deve essere davvero segreto. Se un attaccante lo ottiene, può forgiare token e impersonare qualsiasi utente.
Hashing: Funzioni a Senso Unico
Una funzione hash prende qualsiasi input e produce un output di dimensione fissa. Due proprietà la rendono utile per la sicurezza:
Deterministica: lo stesso input produce sempre lo stesso output.
A senso unico: non puoi invertire l'hash per ottenere l'input originale. Non esiste unhash().
SHA-256("password123") → ef92b778bafe771207...
SHA-256("password124") → 88d4266fd4e6338d13...
Un carattere cambiato. Hash completamente diverso. Nessuna relazione matematica tra input simili e output simili.
Perché le password vengono hashate, non criptate
Se le password fossero criptate, potresti decriptarle con la chiave giusta. Se un attaccante ruba il tuo database e la tua chiave di cifratura, la password di ogni utente è esposta.
Con l'hashing: memorizzi l'hash, non la password. Quando un utente accede, esegui l'hash di ciò che ha digitato e lo confronti con l'hash memorizzato. Se corrispondono, la password è corretta. Non hai mai bisogno di recuperare l'originale — devi solo verificare un'ipotesi.
Anche se un attaccante ottiene il tuo database, ha solo hash. Per ottenere una password, deve indovinare e verificare, il che è molto più lento che semplicemente leggerla.
MD5, SHA-256, bcrypt — perché importa quale usi
MD5 era lo standard nei primi anni 2000. Ora è obsoleto per scopi di sicurezza. Una GPU moderna può calcolare miliardi di hash MD5 al secondo, il che significa che un attaccante con il tuo database può craccare password semplici in minuti con forza bruta. Non usare mai MD5 per le password.
SHA-256 è appropriato per la verifica dell'integrità — confermare che un file non sia stato corrotto o manomesso, generare firme HMAC per webhook API. Ma è troppo veloce per le password. L'hashing veloce è negativo per le password perché rende gli attacchi di forza bruta economici.
bcrypt è progettato specificamente per le password. È intenzionalmente lento — puoi regolare quanti round di calcolo richiede — e include un "salt" integrato (dati casuali) che garantisce che due password identiche producano hash completamente diversi. Questo vanifica gli attacchi con rainbow table (database di hash pre-calcolati).
La regola: usa bcrypt (o Argon2, o scrypt) per le password. Usa SHA-256 per tutto il resto che richiede verifica dell'integrità.
Sperimenta con il Generatore di Hash — digita "password" in MD5, SHA-256 e SHA-512 e confronta le lunghezze dell'output. Poi cambia un carattere e vedi quanto cambia completamente l'hash.
Riferimento Rapido
| Concetto | Cos'è | Puoi invertirlo? | Usalo per |
|---|---|---|---|
| Base64 | Codifica binario → testo | Sì, banalmente | Inviare dati binari attraverso sistemi di testo |
| JWT | Token JSON firmato | Payload: sì. Firma: no | Autenticazione stateless |
| SHA-256 | Funzione hash | No | Integrità file, firme HMAC per webhook |
| bcrypt | Hash per password | No | Memorizzare password utente |
Capire correttamente queste tre cose previene una classe di errori di sicurezza che sembrano corretti nella code review e emergono solo quando qualcosa va storto — a quel punto il danno è già fatto.
Gli strumenti: Base64, Decodificatore JWT, Generatore di Hash. Usali per testare la tua comprensione, non solo per ottenere risultati.