Introducing Cryptography Concepts#
- Hash ≠ cifratura — SHA-256 è one-way, non si decifra. Mai.
- Digest = output di un hash (non del ciphertext)
- Encoding (Base64) ≠ cifratura — è reversibile senza chiave
- CA non serve ovunque — SSH usa TOFU, PGP usa web of trust, CA serve per HTTPS / S/MIME / VPN
- TLS usa entrambe — asimmetrico nell'handshake (lento, pochi byte), simmetrico nella sessione (veloce, bulk data)
- Ciphertext > plaintext — non per magia: padding + IV + auth tag + Base64 encoding
- TRNG ≠ PRNG — stesso input → stesso output (PRNG). TPM e Secure Enclave usano TRNG hardware
- "Provare identità" e "cifrare i dati" sono due operazioni separate — la CA autentica il sito, AES cifra i dati
flowchart TD
classDef spacer fill:none,stroke:none,color:#00000000
subgraph HASH["HASH — one-way, nessuna chiave"]
HS[ ]:::spacer
HS --> H1["Qualsiasi input"] --> H2["Output FIXED size
SHA-256 = 32 byte sempre"]
H2 --> H3["NON reversibile
dall'hash non si ricava l'input"]
H3 --> H4["Scopo: integrità
sha256sum / bcrypt / blockchain"]
end
subgraph SIM["SIMMETRICO — stessa chiave per cifrare e decifrare"]
SS[ ]:::spacer
SS --> S1["Plaintext + chiave K"] --> S2["Ciphertext
più grande dell'input"]
S2 --> |"stessa chiave K"| S3["Plaintext originale"]
S3 --> S4["Scopo: confidenzialità bulk
AES in TLS sessione / VPN / full disk"]
end
subgraph ASIM["ASIMMETRICO — coppia di chiavi, due usi opposti"]
AS[ ]:::spacer
AS --> A1["CIFRATURA
pub key cifra → priv key decifra"]
AS --> A2["FIRMA
priv key firma → pub key verifica"]
A1 --> A3["Scopo: confidenzialità
TLS handshake / S/MIME session key"]
A2 --> A4["Scopo: autenticazione + integrità
firma digitale / CA / S/MIME firma"]
end
subgraph ENC["ENCODING — nessuna chiave, nessuna segretezza"]
ES[ ]:::spacer
ES --> E1["Dati binari"] --> E2["Testo ASCII
Base64 = +33% dimensione"]
E2 --> |"decodifica senza chiave"| E3["Dati originali"]
E3 --> E4["Scopo: trasporto su canali testuali
NON è crittografia"]
end
style HASH fill:#1a1a2a,fill-opacity:0.7,stroke:#58a6ff,color:#58a6ff
style SIM fill:#1a2a1a,fill-opacity:0.7,stroke:#7ec87e,color:#7ec87e
style ASIM fill:#2a1a1a,fill-opacity:0.7,stroke:#e05555,color:#e05555
style ENC fill:#2a2a1a,fill-opacity:0.7,stroke:#c8a858,color:#c8a858
mindmap
root((Cryptography
Core Concepts))
Integrity
Hashing
SHA-3
Fixed-length
Confidentiality
Symmetric
Block cipher
Stream cipher
Asymmetric
PKI
Public key
Private key
Steganography
Authentication
Digital Signature
Non-repudiation
Digital Signature
La crittografia offre quattro servizi fondamentali di sicurezza:
| Servizio | Descrizione | Come si ottiene |
|---|---|---|
| Integrity | I dati non sono stati modificati | Hashing |
| Confidentiality | Solo utenti autorizzati vedono i dati | Encryption |
| Authentication | Valida un'identità | Digital signature, certificati |
| Non-repudiation | Chi ha compiuto un'azione non può negarla | Digital signature |
Providing Integrity with Hashing#
Hash vs Cifratura vs Encoding — tabella rapida:
One-way? Chiave? Output size Esempio Hash / Digest SI NO Fixed (SHA-256 = 32 byte sempre) sha256sum fileCifratura NO SI Variabile, spesso > input AES, RSA Encoding NO NO Variabile (~+33% in Base64) Base64, hex Regola: one-way = hash. Reversibile con chiave = cifratura. Reversibile senza chiave = encoding (non è crittografia). SHA-256 NON è cifratura — è un hash. Non si può recuperare l'input dall'hash. Mai.
Hash vs Cifratura — confronto dettagliato:
Hash / Digest Cifratura (Encryption) Cosa produce impronta digitale (digest) testo cifrato (ciphertext) Dimensione output fixed-size sempre (SHA-256 = 32 byte, punto) variabile, spesso > input Reversibile? NO — one-way, non si torna indietro SI — con la chiave si decifra Chiave necessaria? NO SI Algoritmi SHA-256, SHA-3, MD5, bcrypt AES, RSA, ChaCha20 A cosa serve verificare integrità (il file è cambiato?) proteggere confidenzialità (nessuno legga) Esempio sha256sum file.iso→ 64 hex chars, sempreopenssl enc -aes-256-cbc→ ciphertext piu' grandeHook: Hash = tritacarne (entra la carne, non si ricostruisce). Cifratura = cassaforte (chiudi con chiave, riapri con chiave).
Quando uso cosa — albero decisionale:
flowchart TD
START([Cosa devo fare?]) --> A{Provare identità?}
START --> B{Cifrare dati?}
START --> C{Verificare integrità?}
A -->|SI| A1["Chiave asimmetrica
firma digitale / CA / certificati"]
A1 --> A2["RSA / ECDSA
HTTPS: CA prova identità sito
S/MIME firma / SSH pub key"]
B -->|"Pochi byte
chiave o sessione"| B1["Asimmetrico
lento ma sicuro per key exchange"]
B -->|Tanti dati| B2["Simmetrico
veloce per bulk data"]
B1 --> B3["RSA / ECDHE
TLS handshake / S/MIME session key"]
B2 --> B4["AES
TLS sessione / VPN tunnel / full disk"]
C -->|"Solo integrità
nessuna chiave"| C1["Hash
SHA-256 / SHA-3"]
C -->|"Integrità +
autenticazione"| C2[HMAC o Firma digitale]
C1 --> C3["sha256sum
blockchain / password bcrypt"]
C2 --> C4["HMAC → TLS record layer
Firma → S/MIME / JWT"]
A1 & B3 & C2 --> CROSS(["Spesso si usano insieme
TLS = A+B+C / S/MIME = A+B+C"])
style START fill:#1a2a3a,color:#58a6ff,stroke:#58a6ff
style CROSS fill:#2a1a2a,color:#c88aff,stroke:#c88aff
style A1 fill:#2a1a1a,color:#e05555,stroke:#e05555
style A2 fill:#2a1a1a,color:#e05555,stroke:#e05555
style B1 fill:#2a1a1a,color:#e05555,stroke:#e05555
style B3 fill:#2a1a1a,color:#e05555,stroke:#e05555
style B2 fill:#1a2a1a,color:#7ec87e,stroke:#7ec87e
style B4 fill:#1a2a1a,color:#7ec87e,stroke:#7ec87e
style C1 fill:#1a2a2a,color:#58c8c8,stroke:#58c8c8
style C2 fill:#1a2a2a,color:#58c8c8,stroke:#58c8c8
style C3 fill:#1a2a2a,color:#58c8c8,stroke:#58c8c8
style C4 fill:#1a2a2a,color:#58c8c8,stroke:#58c8c8
L'integrità garantisce che i dati non siano stati modificati. Il confronto di due hash verifica se i dati hanno mantenuto integrità tra il momento in cui sono stati prodotti e il momento in cui vengono ricevuti o usati.
Un hash è una stringa di caratteri alfanumerici (o esadecimali) derivata da un calcolo matematico applicato a un dato: un messaggio, una patch software, un file.
Proprietà fondamentali di un hash:
| Proprietà | Significato |
|---|---|
| Fixed-length | Output di lunghezza fissa indipendentemente dalla dimensione dell'input |
| One-way | Non esiste una funzione matematica inversa: dall'hash non si ricava l'input |
| Avalanche effect | Qualsiasi modifica minima al dato produce un hash completamente diverso |
| Deterministic | Stesso input + stesso algoritmo = sempre lo stesso hash |
"One-way" significa che non esiste una funzione matematica inversa. Non significa che sia impossibile trovare l'input per altri metodi:
- Brute force: prova milioni di input finche' l'hash coincide
- Rainbow tables: dizionario precalcolato
input -> hash. L'attaccante non ricalcola niente al momento del breach: cerca direttamente l'hash nella tabella e recupera la password in millisecondi. Il costo computazionale e' stato pagato una volta sola da chi ha costruito la tabella.
Attaccante prepara la tabella una volta sola:
"password" -> 5f4dcc3b5aa765d61d8327deb882cf99
"password123" -> 482c811da5d5b4bc6d497ffa98491e38
"qwerty" -> d8578edf8458ce06fbc5bb76a58c5ca4
"admin" -> 21232f297a57a5a743894a0e4a801fc3
... miliardi di righe ...
Ottiene un dump di hash dal database violato:
utente@email.com -> 482c811da5d5b4bc6d497ffa98491e38
Cerca 482c811... nella tabella -> trovato -> la password era "password123"Senza salt: hash("password123") = 482c811... (uguale per tutti gli utenti)
Con salt: hash("password123" + "x7kQ") = a93f2b1... (unico per ogni utente)
- Dictionary attack: tenta parole e varianti comuni
Il salt (valore casuale univoco aggiunto a ogni password prima dell'hash) rende inutili le rainbow tables: anche se due utenti hanno la stessa password, il loro hash sara' completamente diverso. L'attaccante non puo' riusare nessuna tabella precalcolata.
HMAC — Hash-based Message Authentication Code#
L'HMAC e' un metodo per fornire sia integrity che authenticity usando hashing + una chiave segreta condivisa.
La differenza strutturale rispetto a un hash normale:
Hash normale: algoritmo(Data) -> hash
HMAC: algoritmo(Key + Data) -> hashHMAC richiede sempre una chiave. Senza chiave non e' HMAC. E' questo che lo distingue da MD5, SHA-256 e tutti gli altri hash: un hash normale accetta solo il dato, HMAC accetta dato + chiave. La chiave e' obbligatoria per definizione.
Produce una stringa a lunghezza fissa come MD5 o SHA-256, ma la shared secret key e' nota solo a mittente e destinatario. Le varianti piu' comuni: HMAC-MD5 e HMAC-SHA256.
Come funziona (esempio server-to-server con HMAC-MD5):
Server A:
1. Calcola MD5 del messaggio
2. Applica la shared secret key al risultato -> HMAC-MD5
3. Invia: messaggio + HMAC-MD5
Server B:
1. Riceve messaggio + HMAC-MD5
2. Esegue gli stessi calcoli con la stessa shared secret key
3. Confronta il proprio risultato con l'HMAC-MD5 ricevuto
- Coincidono -> integrita' + autenticita' verificate
- Differiscono -> messaggio alterato o mittente non autentico| Proprieta' | MD5 da solo | HMAC-MD5 |
|---|---|---|
| Integrity | Si' | Si' |
| Authenticity | No | Si' (solo chi ha la secret key puo' produrre l'hash corretto) |
| Crittograficamente sicuro | No (cracked) | Si', se la secret key e' abbastanza lunga |
Un attaccante che tenta di impersonare il mittente fallisce: non conosce la shared secret key e non puo' produrre l'HMAC corretto.
IPsec e TLS usano versioni di HMAC (HMAC-MD5 e HMAC-SHA256) per garantire integrita' e autenticita' dei pacchetti in transito.
Bitcoin HD Wallet (BIP32 — Master Key Generation): il wallet deterministico gerarchico usa HMAC-SHA512 per derivare la master key dal seed. La formula esatta da specifica BIP32:
I = HMAC-SHA512(Key = "Bitcoin seed", Data = S)La chiave HMAC e' la stringa hardcoded
"Bitcoin seed"(uguale per tutti i wallet Bitcoin).Se' il seed. L'outputI(512 bit) viene diviso: primi 256 bit = master private key, ultimi 256 bit = chain code. Ogni livello di derivazione figlio usa di nuovo HMAC-SHA512.
HMAC = hashing + shared secret key. Fornisce integrity (come qualsiasi hash) + authenticity (solo chi ha la chiave puo' produrre l'HMAC corretto). MD5 da solo e' cracked, HMAC-MD5 e' sicuro se la chiave e' lunga. Usato in IPsec e TLS.
Hashing e' una funzione one-way che crea una stringa alfanumerica. Non si puo' invertire l'hash per ricreare il file originale. Le password sono spesso memorizzate come hash invece del valore in chiaro. Le applicazioni aggiungono un salt alle password prima dell'hashing per difendersi dalle rainbow tables.
Algoritmi crittografici: mappa completa
| Categoria / Algoritmo | Tipo | Dato originale recuperabile? | Come | Usato PER | Usato in |
|---|---|---|---|---|---|
| MD5 | Hashing | Mai | Impossibile per design | Integrity (verifica) | Checksum rapido (deprecato) |
| SHA-256 / SHA-3 | Hashing | Mai | Impossibile per design | Integrity (verifica) | Integrita' file, Bitcoin PoW |
| HMAC | Hashing + chiave | Mai | Impossibile per design | Integrity + Authenticity | IPsec, TLS, BIP32 Bitcoin |
| AES | Cifratura simmetrica | Si' | Con la stessa chiave | Confidentiality | HTTPS, WPA2, disco cifrato |
| RSA | Cifratura asimmetrica | Si' | Con la chiave privata | Confidentiality + Authenticity | TLS handshake, firma digitale |
| Ed25519 / secp256k1 | Firma digitale | No (firma, non cifratura) | La firma non contiene il dato | Authenticity + Non-repudiation | SSH, Bitcoin transazioni |
| Base64 | Encoding | Si' | Sempre, nessuna chiave | Compatibilita' di trasporto | Email, JWT, URL |
| Tokenization | Sostituzione | Si', ma esternamente | Solo consultando la token vault | Ridurre esposizione dati sensibili | PCI DSS, carte di credito |
| Steganography | Occultamento | Si' | Se sai dove cercare | Nascondere l'esistenza del dato | Esfiltrazione nascosta, watermarking |
| Data masking | Mascheramento | No | Originale scartato o separato | Anonimizzazione, privacy | Log, UI (4111 **** **** 1111) |
| Obfuscation | Offuscamento | Parzialmente | Dipende dall'aggressivita' | Scoraggiare lettura (non proteggere) | Malware evasion, protezione codice |
| Dato originale recuperabile? |
Hashing → MAI (one-way per design) Encryption → SÌ, con la chiave Encoding → SÌ, sempre (nessuna chiave) Tokenization → SÌ, ma solo consultando la vault (esternamente) Steganography → SÌ, se sai dove cercare Data masking → NO (l'originale viene scartato o tenuto separato) Obfuscation → PARZIALMENTE (dipende da quanto è aggressiva)
Encryption: il ciphertext deriva matematicamente dal plaintext — con algoritmo + chiave si inverte. Tokenization: il token e' casuale, nessuna relazione con il dato reale — senza consultare la token vault e' inutilizzabile. Per questo e' preferita in PCI DSS: anche rubando tutti i token, non si ricavano i numeri delle carte.
L'algoritmo di hashing standard oggi e' lo Secure Hash Algorithm 3 (SHA-3). Una variante comune e' SHA-3-256, il cui output e' sempre di 64 caratteri esadecimali, indipendentemente dalla dimensione dell'input.
Una proprieta' critica: lo stesso dato, lo stesso algoritmo, produce sempre lo stesso hash. Qualsiasi differenza nel dato (anche un singolo bit) produce un hash completamente diverso.
Esempio pratico: distribuzione di una patch software
Un'azienda rilascia una patch e pubblica sul proprio sito:
Patch file: Patch_v2_3.zip
SHA-3-256 hash: d4723ac6f72daea2c779...3ac113863cIl cliente scarica il file, calcola l'hash localmente e confronta con quello pubblicato. Se coincidono: il file e' identico all'originale, integrita' verificata. Se differiscono: il file e' stato alterato in transito o sul server.
Dev parallel: in PHP
hash_file('sha256', $path)verifica l'integrita' di un file scaricato confrontandolo con l'hash pubblicato dal fornitore. Composer usa SHA-256 incomposer.lockper garantire che ogni dipendenza installata sia byte-per-byte identica a quella attesa.
Hashing verifica l'integrita' per email, file scaricati e file su disco. Un hash e' un numero esadecimale creato con un algoritmo di hashing. Non e' cifratura: non si "decritta" un hash.
Hashing Files#
Molte applicazioni calcolano e confrontano gli hash automaticamente, senza intervento dell'utente. Le firme digitali nelle email, ad esempio, usano hashing internamente e le applicazioni email creano e confrontano gli hash in modo trasparente.
E' anche possibile calcolare hash manualmente con strumenti come sha256sum (Linux/macOS) o sha256sum.exe (Windows).
Esempio reale: download immagine Kali Linux

File scaricato: kali-linux-*.iso
SHA-256 atteso: acf455e6f9ab0720df0abed15799223c2445882b44dfcc3f2216f9464db7915
SHA-256 calcolato: acf455e6f9ab0720df0abed15799223c2445882b44dfcc3f2216f9464db7915
Risultato: MATCH -> file integroGli amministratori di kali.org calcolano l'hash sull'immagine originale e pubblicano sia il file che il suo hash. Dopo il download, si ricalcola l'hash localmente e si confronta:
- Hash coincide: il file scaricato e' identico all'originale pubblicato
- Hash diverso: il file ha perso integrita', corrotto in transito o modificato dopo la pubblicazione. Il file non va usato.
Eseguendo sha256sum tre volte sullo stesso file si ottiene sempre lo stesso risultato. Questo dimostra due punti chiave:
- L'hash e' sempre lo stesso, indipendentemente da quante volte lo si calcola con lo stesso algoritmo
- Hashing verifica l'integrita': hash calcolato = hash pubblicato -> file non alterato
Hashing e' one-way: nessuna informazione sull'originale
Dall'hash non si ricava nulla sul dato originale: ne' la dimensione, ne' il tipo, ne' il contenuto.
Messaggio: "I will pass the Security+ exam"
SHA-1: 765591c4611be5e03bea41882ffdaa159352cf49Guardando l'hash 765591c4... non si puo' sapere che e' il digest di una frase di sei parole. Allo stesso modo, l'hash SHA-256 di un file da 2,9 GB non e' piu' grande di quello di un file da 1 KB: entrambi producono 64 caratteri esadecimali.
Hashing Messages#

Hashing garantisce l'integrita' dei messaggi: chi riceve un messaggio ha la prova che non e' stato modificato in transito.
Esempio: Lisa invia un messaggio a Bart
Lisa calcola:
Messaggio: "The price is $75."
MD5 hash: D9B93C99B62646ABD06C887039053F56
Invia: messaggio + hash
[qualcosa modifica il messaggio in transito]
Bart riceve:
Messaggio: "The price is .75." <- modificato
Hash: D9B93C99B62646ABD06C887039053F56 <- invariato
Bart ricalcola:
MD5 del messaggio ricevuto: 564294439E1617F5628A3E3EB75643FE
Confronto:
Hash ricevuto: D9B93C99B62646ABD06C887039053F56
Hash calcolato: 564294439E1617F5628A3E3EB75643FE
Risultato: MISMATCH -> integrita' persaBart non conosce la causa: attacco intenzionale o problema tecnico. Ma sa con certezza che il messaggio ricevuto non e' identico al messaggio inviato e non va considerato affidabile.
In questo esempio il messaggio non e' cifrato: hashing garantisce integrita', non confidenzialita'. Sono due servizi distinti che si possono usare insieme o separatamente.
Saper riconoscere gli algoritmi di hashing (MD5, SHA, HMAC) permette di eliminare rapidamente opzioni errate. Se una domanda chiede come cifrare i dati e nelle opzioni compaiono MD5, SHA o HMAC: eliminali subito. Gli algoritmi di hashing non cifrano i dati.
Il problema dell'hash semplice: attacco all'hash#

L'esempio Lisa/Bart mostra il caso di un'alterazione accidentale. Ma un attaccante attivo puo' fare di piu': non solo modificare il messaggio, ma ricalcolare l'hash sul messaggio modificato e sostituire anche quello.
Scenario attacco completo (Hacker Harry):
Lisa invia:
Messaggio: "The price is $75."
MD5 hash: D9B93C99B62646ABD06C887039053F56
Harry intercetta e modifica:
Messaggio: "The price is .75."
Ricalcola: 564294439E1617F5628A3E3EB75643FE
Sostituisce anche l'hash originale con quello nuovo
Bart riceve:
Messaggio: "The price is .75."
Hash: 564294439E1617F5628A3E3EB75643FE <- hash di Harry
Bart ricalcola:
MD5: 564294439E1617F5628A3E3EB75643FE
Confronto: MATCH -> Bart pensa che il messaggio sia integroCon il solo MD5, l'attacco e' invisibile. Bart non ha modo di distinguere questo scenario da un messaggio legittimo.
HMAC risolve il problema
Con HMAC, Lisa e Bart condividono una shared secret key che Harry non conosce. L'hash non e' piu' calcolabile senza la chiave.
Lisa calcola (con shared secret key):
MD5 del messaggio: D9B93C99B62646ABD06C887039053F56
HMAC-MD5 (con chiave): 733C70A54A13744D5C2C9C4BA3B15034
Invia: messaggio + HMAC-MD5
Harry modifica il messaggio, ma NON conosce la shared secret key
-> non puo' produrre l'HMAC-MD5 corretto per il messaggio modificato
Bart ricalcola HMAC-MD5 (con la stessa shared secret key):
HMAC-MD5 ricevuto: 733C70A54A13744D5C2C9C4BA3B15034
HMAC-MD5 calcolato: 1B4FF0F6C04434BF97F1E3DDD4B6C137
Confronto: MISMATCH -> messaggio alterato rilevatoQuesto e' il motivo per cui HMAC fornisce sia integrity che authenticity: l'hash puo' essere prodotto solo da chi conosce la shared secret key.
Questa e' la domanda fondamentale della crittografia simmetrica: il key distribution problem. La shared secret non puo' viaggiare in chiaro sullo stesso canale che si vuole proteggere. Le soluzioni:
- Out-of-band: gli amministratori la configurano manualmente nei due sistemi (file di config, procedura sicura separata). Adatto a due server fissi.
- Crittografia asimmetrica: la shared secret viene cifrata con la chiave pubblica del destinatario e inviata. Solo chi ha la chiave privata corrispondente puo' decifrarla.
- Diffie-Hellman: protocollo che permette a due parti di accordarsi su una chiave comune attraverso un canale pubblico, senza mai trasmetterla direttamente.
TLS usa esattamente questo: handshake asimmetrico per scambiare le session keys (incluse quelle HMAC), poi comunicazione simmetrica. Vedi cap-03-security-architecture sezione TLS.
Questo non rende HMAC "quasi asimmetrico". Sono due livelli distinti: la crittografia asimmetrica viene usata una volta sola per consegnare la shared secret in modo sicuro (bootstrapping). Dopo, HMAC lavora in modo puramente simmetrico per ogni messaggio. E' un pattern ibrido deliberato: asimmetrico e' lento e costoso, non si puo' usare per autenticare ogni pacchetto. Lo si usa solo per il key exchange iniziale, poi il simmetrico fa il lavoro pesante.
Hashing Passwords#
La maggior parte dei sistemi non memorizza la password in chiaro. Memorizza l'hash della password.
Come funziona:
Creazione account:
Utente imposta password "abc123"
Sistema calcola hash("abc123") -> 6367c48dd193d56ea7b0baad25b19455
Sistema salva: { username: "mario", hash: "6367c48..." } <- non la password
Login:
Utente inserisce "abc123"
Sistema calcola hash("abc123") -> 6367c48dd193d56ea7b0baad25b19455
Confronto con hash memorizzato -> MATCH -> accesso consentitoLe password raramente vengono trasmesse in cleartext sulla rete: viene inviato l'hash, non la password originale.
Il problema: database di hash precalcolati
Strumenti come MD5 Online usano un database di hash precalcolati. Inserisci un hash, restituisce la password in chiaro se il match viene trovato.
Password: "12345"
MD5 hash: 827ccb0eea8a706c4c34a16891f84e7b
MD5 Online: inserisci l'hash -> restituisce "12345" in meno di un secondoQuesto e' esattamente il principio delle #Rainbow tables viste in precedenza: il costo computazionale e' stato pagato una volta sola da chi ha costruito il database. La ricerca e' istantanea.
Soluzione parziale: usare SHA-3 invece di MD5
Solo algoritmi forti come SHA-3 dovrebbero essere usati per memorizzare gli hash delle password. MD5 e' cracked e i suoi hash sono ampiamente presenti nei database precalcolati.
Anche SHA-3 da solo non basta. Le password vanno sempre salted: un valore casuale univoco viene aggiunto a ogni password prima dell'hashing. Il salt rende inutili tutti i database precalcolati esistenti. Gibson tratta il salting piu' avanti nel capitolo.
Dev parallel: in PHP il modo corretto e'
password_hash($password, PASSWORD_BCRYPT)che aggiunge automaticamente un salt univoco.password_verify()per il confronto. Mai usaremd5($password)osha1($password)direttamente per le password.
Hash Collisions#
Una hash collision si verifica quando un algoritmo di hashing produce lo stesso hash da input diversi.
Esempio con un algoritmo ipotetico a 3 cifre:
hash("success") = 123
hash("passed") = 123 <- collisioneIn questo scenario l'attaccante non ha bisogno di indovinare la password corretta: basta trovare qualsiasi input che produca lo stesso hash. Entrambe le password passerebbero il controllo.
MD5 e' altamente suscettibile agli hash collision attacks: e' possibile costruire deliberatamente due input diversi che producono lo stesso hash MD5. Questo e' uno dei motivi principali per cui MD5 non e' piu' raccomandato come hash crittografico.
Hash collision = stesso hash, input diversi. MD5 e' vulnerabile. SHA-3 e' resistente alle collisioni by design.
Password Attacks#
I password attack tentano di scoprire o aggirare le password usate per l'autenticazione.
Online password attack
Tenta di scoprire una password da un sistema attivo e raggiungibile. L'attaccante prova username e password ripetutamente, spesso con tool automatizzati.
ncrack e' un tool gratuito per eseguire online brute force attacks.
Indicatori nei log:
| Event ID (Windows) | Significato |
|---|---|
| 4625 | Failed logon (tentativo di accesso fallito) |
| 4740 | Account locked out (troppi tentativi falliti) |
Questi eventi si trovano nel Security log di Windows, visualizzabile in Event Viewer. Ripetizioni di 4625 seguite da 4740 sono un indicatore chiaro di brute force in corso.
Offline password attack
Tenta di scoprire password da un database catturato o da un packet capture, senza interagire con il sistema target. Dopo un data breach, gli attaccanti scaricano interi database di hash e li attaccano localmente, senza limiti di tentativi e a velocita' massima.
| Online | Offline | |
|---|---|---|
| Target | Sistema attivo | Database o capture scaricato |
| Velocita' | Lenta (latenza di rete, lockout) | Molto veloce (solo CPU/GPU locale) |
| Rilevabile | Si' (log, lockout) | No (avviene fuori dal sistema) |
| Esempio | ncrack su SSH | Hashcat su dump del database |
Dev parallel: un attacco offline su un database MySQL violato e' esattamente il motivo per cui bcrypt (e non MD5) va usato per le password: bcrypt e' deliberatamente lento e resistente alla GPU, rendendo il brute force offline enormemente piu' costoso.
Dictionary Attack#
Un dictionary attack usa un dizionario di parole e prova ogni combinazione come password. Il "dizionario" in questo contesto e' una lista di parole e combinazioni di caratteri, non un dizionario linguistico.
I dizionari usati negli attacchi si sono evoluti per riflettere il comportamento reale degli utenti: includono password comuni, varianti prevedibili, sostituzioni tipiche (a->@, e->3), e stringhe come "12345" che non sono parole di dizionario ma sono usate da milioni di persone.
La difesa e' usare password complesse che non compaiano in nessun dizionario.
Nel lab analisi-attacco-hydra-wazuh abbiamo eseguito esattamente questo: hydra -l root -P /usr/share/wordlists/rockyou.txt ssh://192.168.64.3 -t 4. rockyou.txt e' il dizionario (14 milioni di password comuni). Hydra prova ogni riga contro SSH. E' un online dictionary attack: interagisce con il sistema live, genera log visibili (816 failed login in pochi minuti), e viene bloccato da fail2ban dopo 5 tentativi.
La difesa e' la stessa che Gibson indica: password complessa che non compaia in nessun dizionario. "12345" viene trovata in meno di un secondo. Una password random di 20 caratteri non sara' mai in rockyou.txt.
Brute Force Attack#
Un brute force attack prova tutte le possibili combinazioni di caratteri, sistematicamente. Non usa un dizionario: genera ogni combinazione possibile.
Difese:
- Password complessa: mix di maiuscole, minuscole, numeri e caratteri speciali
- Password lunga: ogni carattere aggiuntivo moltiplica esponenzialmente le combinazioni possibili
- Hash robusto: usare bcrypt o SHA-3, non MD5 (lento by design = brute force offline molto costoso)
Password Spraying Attack#
Il password spraying e' una variante di brute force/dictionary progettata specificamente per aggirare l'account lockout policy.
Differenza rispetto al brute force classico:
Brute force classico:
account: mario.rossi
prova: password1, password2, password3 ... -> LOCKOUT dopo N tentativi
Password spraying:
password: "Summer2024!"
prova: mario.rossi, luigi.verdi, anna.bianchi, ... (tutti gli account)
password: "Welcome1"
prova: mario.rossi, luigi.verdi, anna.bianchi, ... (tutti di nuovo)Passando da un account all'altro, l'attaccante raramente supera la soglia di tentativi falliti per singolo account entro il time window configurato nel lockout policy. Il lockout non scatta.
Come rilevarlo nei log:
| Attacco | Event ID 4625 | Event ID 4740 | Pattern |
|---|---|---|---|
| Brute force / dictionary | Molti, ravvicinati | Si' (lockout) | Stesso account, raffica rapida |
| Password spraying | Molti, distribuiti | Raramente | Account diversi, intervalli temporali tra le voci |
Con IP rotation lo spraying diventa ancora piu' silenzioso: ogni tentativo arriva da IP diverso, nessun pattern geografico, nessun lockout. I singoli tentativi sembrano login legittimi distribuiti. Senza un SIEM che correla gli eventi su piu' account, e' quasi invisibile.
Pass the Hash Attack#
In un pass the hash attack, l'attaccante non indovina la password: ruba direttamente l'hash e lo usa per autenticarsi al posto dell'utente. Qualsiasi protocollo che trasmette l'hash in formato non cifrato e' vulnerabile.
Storicamente associato a LM (LAN Manager) e NTLM (NT LAN Manager), due protocolli Microsoft obsoleti. Ha avuto successo anche contro Kerberos.
Come funziona:
Step 1 — Accesso amministrativo:
L'attaccante compromette un sistema con privilegi admin
(via malware, exploit, o utente loggato come admin)
Se il sistema e' infetto da malware: stessi privilegi dell'utente corrente
Step 2 — Furto degli hash:
Posizioni dove risiedono gli hash su Windows:
- SAM database (Security Accounts Manager)
- LSASS process (Local Security Authority Subsystem Service)
- CredMan store (Credential Manager)
- LSA Secrets nel Registry
Step 3 — Lateral movement:
L'attaccante usa l'hash rubato per autenticarsi su altri computer della rete
senza mai conoscere la password in chiaroLa forza della password non conta nulla contro pass the hash: l'attaccante non deve indovinarla. Una password di 50 caratteri ha lo stesso hash rubabile di una da 6. La difesa e' limitare i privilegi admin e isolare i sistemi.
Su un web server normale, mandare l'hash al posto della password non funziona: il server hasha quello che riceve, ottenendo hash(hash) != hash(password). Autenticazione fallita.
Pass the hash funziona solo contro protocolli progettati per ricevere l'hash direttamente come segreto:
- NTLM / SMB / condivisioni Windows / WinRM / RDP: il protocollo chiede l'hash NT, non la password. L'attaccante manda lo stesso hash rubato e il server non distingue.
- SSH, HTTP, form web: pass the hash non funziona. Il server ri-hasha l'input ricevuto.
La vulnerabilita' e' nel design del protocollo, non nel concetto di hashing in generale.
Birthday Attack#
Un birthday attack sfrutta il birthday paradox della teoria della probabilita': in un gruppo di 23 persone, c'e' il 50% di probabilita' che due abbiano lo stesso compleanno (uno dei 366 giorni dell'anno).
L'intuizione controintuitiva: non serve esplorare tutte le possibilita' per trovare una collisione. Basta esplorarne una piccola frazione.
In crittografia: l'attaccante non cerca la password originale. Cerca qualsiasi password che produca lo stesso hash (hash collision). Applicando la logica del birthday paradox, il numero di tentativi necessari per trovare una collisione e' molto minore del numero totale di hash possibili.
Esempio reale: attacco a certificati digitali (2008)
Il birthday attack si usa principalmente contro le firme digitali, non direttamente contro le password.
Obiettivo: ottenere un certificato CA fasullo firmato da una CA reale
Step 1: genera migliaia di varianti del certificato LEGITTIMO
"Cert per barno.com v1" -> MD5: A3F2...
"Cert per barno.com v2" -> MD5: 9B1D...
"Cert per barno.com v3" -> MD5: C4E7...
Step 2: genera migliaia di varianti del certificato MALEVOLO (CA fasullo)
"Cert CA malevolo v1" -> MD5: 7F3A...
"Cert CA malevolo v2" -> MD5: A3F2... <- COLLISIONE trovata!
Step 3: porta il certificato LEGITTIMO alla CA reale -> viene firmato
Step 4: sostituisce con il certificato MALEVOLO (stesso hash MD5 -> stessa firma valida)
Step 5: ora possiede un certificato CA firmato da una CA reale
-> puo' firmare certificati per qualsiasi sito come se fosse legittimoNon ha indovinato nessuna password e non ha violato la CA. Ha trovato due documenti diversi con lo stesso hash MD5. La firma era matematicamente valida per entrambi.
Difesa: aumentare i bit dell'hash
Piu' bit = piu' hash possibili = piu' tentativi necessari per trovare una collisione:
| Algoritmo | Bit | Vulnerabile a birthday attack |
|---|---|---|
| MD5 | 128 bit | Si' |
| SHA-3 | fino a 512 bit | No |
Birthday attack = sfrutta le collisioni. Hash collision = stesso hash da password diverse. Difesa: hash con piu' bit (SHA-3 fino a 512 bit). Salt difende da rainbow table, non da birthday attack direttamente.
Rainbow Table Attack#
Una rainbow table e' un database enorme di password con i loro hash precalcolati. Alcune rainbow table raggiungono 690 GB e coprono tutte le combinazioni di caratteri fino a 9 caratteri di lunghezza.
Perche' e' piu' veloce del brute force:
Senza rainbow table (brute force):
1. Indovina una password
2. Calcola l'hash <- operazione costosa, ripetuta milioni di volte
3. Confronta con l'hash target
4. Ripeti
Con rainbow table:
1. Cerca l'hash target nella tabella <- solo una lookup, il calcolo e' gia' stato fatto
2. Trovato -> password corrispondenteL'eliminazione del calcolo dell'hash rende l'attacco ordini di grandezza piu' veloce. Solitamente eseguito offline su database rubati.
Salting Passwords#
Il salt e' un insieme di dati casuali (anche solo due caratteri) aggiunto alla password prima dell'hashing.
Senza salt: hash("password123") = 482c811... (uguale per tutti)
Con salt: hash("password123" + "xK9m") = a7f3c2... (unico per ogni utente)
hash("password123" + "Qp2r") = 9b1d4e... (diverso anche con stessa password)Il salt rende inutili le rainbow table: nessuna tabella precalcolata contiene hash di password+salt casuali. L'attaccante dovrebbe ricostruire l'intera tabella da zero per ogni salt, rendendo l'attacco computazionalmente impraticabile.
Difende da: rainbow table attacks, brute force, dictionary attacks.
Salt = dati casuali aggiunti alla password prima dell'hash. Rende inutili le rainbow table. Due utenti con la stessa password avranno hash diversi grazie al salt diverso.
Key Stretching#
Il key stretching va oltre il semplice salt: applica un algoritmo crittografico iterativo alla password saltata. Il beneficio principale e' che consuma deliberatamente piu' tempo e risorse computazionali, rendendo il brute force molto piu' costoso per l'attaccante.1
Salt semplice: hash(password + salt) -> veloce (ms)
Key stretching: algoritmo(password + salt) x N -> lento (centinaia di ms)Per un utente legittimo la differenza e' impercettibile (300ms vs 1ms). Per un attaccante che prova milioni di combinazioni, moltiplica il costo per milioni.
Tre algoritmi principali:
| Algoritmo | Base | Output | Usato in |
|---|---|---|---|
| bcrypt | Blowfish block cipher | 60 char (stringa fissa) | Unix/Linux shadow file |
| PBKDF2 | HMAC (pseudo-random) | 128/256/512 bit | WPA2, iOS, Cisco IOS |
| Argon2 | Vincitore PHC 2015 | variabile | Standard moderno consigliato |
bcrypt
Basato sul cifrario Blowfish. Aggiunge salt casuale, cifra con Blowfish, ripete il processo piu' volte. Il risultato e' sempre una stringa di 60 caratteri:
Password: "ILOve$ecurity"
bcrypt: $2b$12$HXIKtJr93DH59BzzKQhehOI9pGjRA/03ENcFRby1jH7nXwt1Tn0kG
^ ^
| iterazioni (12 = 2^12 = 4096 rounds)
versione bcryptIl parametro iterazioni e' configurabile: piu' alto = piu' lento = piu' sicuro. Si puo' aggiungere anche un pepper: un secondo set di bit casuali memorizzato separatamente (es. in una variabile d'ambiente, non nel database). Se il database viene rubato, il pepper manca.2
PBKDF2
Usa HMAC come funzione pseudo-random. Salt minimo 64 bit. Fino a 1.000.000 di iterazioni.3
Usato in WPA2, iOS, Cisco IOS. Debolezza: puo' essere configurato per usare meno tempo e RAM, rendendo l'attacco piu' facile se mal configurato.
Argon2
Vincitore del Password Hashing Competition (PHC) del 2015. Varianti: Argon2d, Argon2i, Argon2id (ibrido). Progettato per resistere anche ad attacchi con hardware specializzato (GPU, ASIC). Standard moderno raccomandato.
bcrypt, PBKDF2, Argon2 = key stretching. Salt + algoritmo iterativo = piu' lento = piu' costoso per l'attaccante. bcrypt output = 60 char. PBKDF2 usa HMAC.
Rilevamento nei log Windows:
| Event ID | Significato | Indicatore sospetto |
|---|---|---|
| 4624 | Successful logon | Logon Process = NTLMSSP e/o Auth Package = NTLM |
| 4672 | Special privileges assigned | Privilegi admin usati da account non-admin su computer remoti |
Gli utenti normali non usano privilegi admin per connettersi ad altri computer. Un pass the hash in corso mostra 4624 con NTLMSSP + 4672 con privilegi elevati su piu' macchine della rete = lateral movement.
Pass the hash usa un hash intercettato, non la password. Rilevabile con Event ID 4624 (Logon Process = NTLMSSP e/o Authentication Package = NTLM). Correlare con 4672 per identificare l'uso di privilegi admin nel lateral movement.
Online = sistema attivo (genera log, possibile lockout). Offline = file scaricato (nessun log, nessun lockout, velocita' massima). Log: 4625 = failed logon, 4740 = account locked out. Spraying = 4625 presenti ma con intervalli di tempo e account diversi, 4740 assente o raro.
Hash vs Checksum#

Hash e checksum sono simili nello scopo (verificare integrita') ma diversi per lunghezza, forza e contesto d'uso.
| Hash | Checksum | |
|---|---|---|
| Lunghezza | Lunga (SHA-3-256 = 64 char hex) | Breve (spesso 1-2 bit) |
| Scopo | Verifica crittograficamente sicura | Verifica rapida integrita' |
| Sicurezza | Crittograficamente sicuro | Non crittograficamente sicuro |
| Esempio | SHA-3 di una patch software | RAID-5 parity bit, check digit carta di credito |
Esempio RAID-5: usa un singolo parity bit per byte. Puo' identificare dati corrotti ma non resiste ad attacchi intenzionali.
Esempio carta di credito a 16 cifre:
| Cifre | Contenuto |
|---|---|
| 1-6 | Institution identifier (banca emittente) |
| 7-15 | Numero di conto |
| 16 | Check digit (checksum) |
Come funziona: il checksum viene calcolato due volte, senza il check digit e poi con il check digit. Se i risultati coincidono, il numero e' stato inserito correttamente. Se no, l'applicazione mostra un errore prima ancora di tentare la transazione.
I checksum non sono crittograficamente sicuri: danno una verifica rapida contro errori accidentali, non contro manipolazioni intenzionali. SHA-3 invece resiste ad attacchi.
Perche' gli hash sono in esadecimale#
Gli hash vengono mostrati in formato esadecimale invece che come flusso di bit binari (1 e 0). Il motivo e' pratico: e' piu' compatto e leggibile.
La relazione chiave:
1 carattere hex = 4 bit (nibble)I caratteri hex usano: cifre 0-9 e lettere a-f (16 simboli totali = 2^4 = 4 bit).
Questo spiega direttamente la lunghezza degli hash in caratteri:
| Algoritmo | Bit | Calcolo | Char hex |
|---|---|---|---|
| MD5 | 128 bit | 128 / 4 | 32 char |
| SHA-1 | 160 bit | 160 / 4 | 40 char |
| SHA-256 | 256 bit | 256 / 4 | 64 char |
| SHA-3-256 | 256 bit | 256 / 4 | 64 char |
Se vedi 32 caratteri hex -> MD5. Se vedi 64 caratteri hex -> SHA-256 o SHA-3-256. La lunghezza dell'hash rivela l'algoritmo usato.
MD5 — Message Digest 5#
MD5 produce un hash di 128 bit (32 caratteri hex). In uso dal 1992.
Nel 2004 sono state scoperte vulnerabilita' significative. Con l'aumento della potenza di calcolo, sfruttarle e' diventato sempre piu' semplice. MD5 e' oggi considerato cracked e il suo uso come hash crittografico e' sconsigliato.
Viene ancora usato come checksum rapido (non crittografico) per verificare integrita' di: email, file su disco, file scaricati da Internet, eseguibili.
MD5 non va usato per applicazioni di sicurezza: autenticazione, firme digitali, integrità critica. Solo per verifiche rapide dove un attaccante non e' nel threat model.
Secure Hash Algorithms (SHA)#
SHA e' una famiglia di algoritmi raggruppata in quattro standard:
| Standard | Bit | Char hex | Stato |
|---|---|---|---|
| SHA-0 | - | - | Difettoso, non usato |
| SHA-1 | 160 bit | 40 char | Debolezze scoperte, non approvato per usi crittografici |
| SHA-2 (SHA-224) | 224 bit | 56 char | Versione troncata di SHA-256 |
| SHA-2 (SHA-256) | 256 bit | 64 char | Standard attuale, ampiamente usato |
| SHA-2 (SHA-384) | 384 bit | 96 char | Versione troncata di SHA-512 |
| SHA-2 (SHA-512) | 512 bit | 128 char | Alta sicurezza |
| SHA-3 | 224/256/384/512 bit | come SHA-2 | Alternativa indipendente a SHA-2 |
SHA-3 (ex Keccak): a differenza di SHA-1 e SHA-2, creato fuori dalla NSA e selezionato tramite competizione pubblica internazionale. Produce hash delle stesse dimensioni di SHA-2, ma con architettura interna completamente diversa. Questo e' importante: se venissero scoperte debolezze in SHA-2, SHA-3 resterebbe sicuro perche' non condivide la stessa base.
SHA-1 = 160 bit = 40 char hex. SHA-256 = 256 bit = 64 char hex. SHA-3 e' l'alternativa a SHA-2 creata fuori dalla NSA in competizione pubblica.
Uso pratico: HIDS e integrità degli eseguibili
I file eseguibili raramente vengono modificati in condizioni normali. Alcuni malware pero' aggiungono codice malevolo direttamente dentro un eseguibile esistente.
I sistemi HIDS (Host-based Intrusion Detection System) e i software antivirus sfruttano questa proprieta':
1. Prima scansione: cattura hash di tutti i file eseguibili e di sistema
2. Scansione successiva: ricalcola gli hash degli stessi file
3. Confronto: hash diverso -> file modificato -> possibile malwareGli hash validi dei file di sistema sono inclusi nei file di definizione delle signature. Se l'hash di un eseguibile cambia tra una scansione e l'altra, e' un indicatore di compromissione.
Dev parallel: stesso principio dei lock file in Node.js (package-lock.json). L'hash SHA-512 di ogni pacchetto viene salvato al momento dell'installazione. A ogni
npm ci, gli hash vengono ricalcolati e confrontati. Se qualcuno ha manomesso un pacchetto nel registry, l'hash non corrisponde e l'installazione fallisce.
Questa capacita' e' parte di EDR e HIPS (vedi cap-03-security-architecture): il monitoraggio dell'integrita' dei file eseguibili e' una delle funzioni core della protezione endpoint.
Providing Confidentiality with Encryption#

La confidentiality garantisce che i dati siano visibili solo agli utenti autorizzati. La crittografia protegge la confidenzialita' dei dati.
Plaintext = dati leggibili da un umano. Encryption = l'algoritmo scrambles (rimescola) il plaintext, producendo ciphertext — illeggibile senza la chiave. Ciphertext = output cifrato. Un attaccante che intercetta traffico cifrato vede solo ciphertext inutilizzabile.
Se invece i dati viaggiano in cleartext (non cifrati), un attaccante con un protocol analyzer legge tutto in chiaro.
L'encryption include sempre due elementi:
- Algorithm: esegue i calcoli matematici sui dati. E' sempre lo stesso e pubblicamente noto.
- Key: un numero che introduce variabilita'. Viene tenuto segreto e/o cambiato frequentemente. E' la chiave (letteralmente) della sicurezza.
Esempio concreto con AES-256:
Algorithm: AES (Advanced Encryption Standard) — pubblico, uguale per tutti
Key: a3f8c2... (256 bit casuali) — segreto, unico per questa sessione
Plaintext: "Carta: 4111 1111 1111 1111"
+ Algorithm AES
+ Key a3f8c2...
= Ciphertext: x7Kq#mP2nR9...
Se cambio la Key (ma tengo lo stesso Algorithm AES):
+ Key b9d1e4...
= Ciphertext completamente diverso: Zp3Lw8vQ...
Stesso algoritmo, chiave diversa -> output completamente diverso.
Questo e' il motivo per cui l'algoritmo puo' essere pubblico:
senza la chiave, il ciphertext e' inutile.La sicurezza dell'encryption dipende dalla segretezza della chiave, non dalla segretezza dell'algoritmo. AES e' pubblico e analizzato da tutti — e' piu' sicuro per questo.
Glossario inglese/italiano — crittografia
| Inglese | Italiano |
|---|---|
| Encryption | Cifratura |
| To encrypt | Cifrare |
| Decryption | Decifratura |
| To decrypt | Decifrare |
| Cipher | Cifrario |
| Ciphertext | Testo cifrato |
| Plaintext / Cleartext | Testo in chiaro |
| Hashing | Hashing (non si traduce) |
| Hash | Hash / impronta digitale |
| To hash | Calcolare l'hash |
| Salt | Salt (non si traduce) |
| Key | Chiave |
| Key pair | Coppia di chiavi |
| Obfuscation | Offuscamento |
| Digital signature | Firma digitale |
Data at rest / in transit / in use4
| Stato | Descrizione | Esempio | Cifratura comune |
|---|---|---|---|
| At rest | Dati memorizzati su un supporto | Database, file su disco | Campo cifrato nel DB, full disk encryption |
| In transit | Dati inviati su rete | Transazione e-commerce | HTTPS, TLS |
| In use | Dati in elaborazione in memoria | App che processa dati | Non cifrati (CPU deve leggerli) |
I dati in use non sono cifrati: la CPU deve poterli processare. Un'applicazione decifra i dati in memoria per usarli, poi li ricifra prima di salvarli. Dopo l'uso, le applicazioni ben scritte azzerano la memoria per non lasciare dati sensibili in RAM.
Symmetric Encryption#
La symmetric encryption usa la stessa chiave per cifrare e decifrare. Nomi alternativi: secret-key encryption, session-key encryption.
Esempio con cifrario a sostituzione (ROT+N):
Algorithm: sposta ogni lettera N posizioni avanti (cifratura) / indietro (decifratura)
Key: N = 3
Plaintext: P A S S
+3 +3 +3 +3
Ciphertext: S D V V
Decryption: S D V V
-3 -3 -3 -3
Plaintext: P A S SROT13: stesso principio ma chiave sempre fissa = 13. Non e' vera encryption ma solo obfuscation per due motivi precisi:
- La chiave (13) e' pubblica per convenzione — non c'e' segreto
- Chiunque conosce ROT13 puo' decifrare qualsiasi messaggio senza che tu gliela dica
La segretezza della chiave e' cio' che distingue vera encryption da obfuscation. AES con chiave segreta = encryption. ROT13 con chiave nota a tutti = obfuscation.
La security through obscurity ("sicurezza per oscurita'") conta sulla segretezza dell'algoritmo invece che della chiave — non e' mai un metodo affidabile.5
Dove si colloca l'hashing in questo schema:
| Metodo | Chiave segreta | Reversibile | Scopo |
|---|---|---|---|
| Symmetric encryption (AES) | Si', segreta | Si' (con la chiave) | Confidenzialita' |
| Asymmetric encryption (RSA) | Si', privata | Si' (con chiave privata) | Confidenzialita' + scambio chiavi |
| Hashing (SHA-3) | No | Mai | Integrita' |
| Obfuscation (ROT13) | No (chiave nota) | Si' (banalmente) | Nessuno — non e' sicurezza |
| Symmetric | Asymmetric | |
|---|---|---|
| Chiavi | Una sola chiave per cifrare e decifrare | Due chiavi (pubblica + privata) come coppia abbinata |
| Velocita' | Piu' veloce | Piu' lenta |
| Problema principale | Come si scambia la chiave in modo sicuro? | Risolto: la chiave pubblica si distribuisce liberamente |
| Richiede PKI | No | Si' |
| Modalita' | Block cipher o Stream cipher | - |
AES (Advanced Encryption Standard) usa tipicamente chiavi da 128 bit, ma supporta anche 192 o 256 bit.
Analogia: chiave di casa
La chiave simmetrica funziona come una chiave di casa: Marge ha una chiave che apre e chiude la porta. Fa una copia per Homer. Ora entrambi possono aprire e chiudere con la stessa chiave. Se qualcuno entra in possesso della chiave, pero', puo' aprire la porta.
Cambio frequente delle chiavi
La symmetric encryption non usa sempre la stessa chiave. L'analogia di Gibson: due amici decidono una chiave diversa ogni mattino andando a scuola. Se ieri qualcuno craccasse quella chiave, non servirebbe per decifrare i messaggi di oggi.
Gli algoritmi cambiano chiave molto piu' spesso — praticamente per ogni dato diverso:
Progetto.pdf cifrato con key = 123
Budget.xlsx cifrato con key = 456
key 123 decifra SOLO Progetto.pdf
key 456 decifra SOLO Budget.xlsxRischi del riuso della chiave:
- Piu' facile da craccare — piu' ciphertext prodotto con la stessa chiave = piu' pattern analizzabili
- Blast radius — se la chiave viene scoperta, tutti i dati cifrati con quella chiave sono compromessi
Analisi CIA — perdita o compromissione della symmetric key
La symmetric key e' un single point of failure: una sola chiave gestisce tutto in entrambe le direzioni.
| CIA | Chiave persa (nessuno ce l'ha) | Chiave compromessa (rubata) |
|---|---|---|
| Confidentiality | Mantenuta — nessuno decifra, nemmeno tu | Violata in entrambe le direzioni: l'attaccante legge tutto |
| Integrity | Non applicabile (symmetric non firma) | Violata — l'attaccante modifica e ri-cifra senza lasciare tracce |
| Availability | Catastrofica — tutto il dato cifrato e' perso per sempre | Mantenuta per te, ma il sistema e' da considerarsi bruciato |
La compromissione della symmetric key e' piu' pericolosa di quella della private key asimmetrica: chi la ottiene controlla la comunicazione in entrambe le direzioni (legge e scrive), mentre la private key compromessa dà solo il ruolo del titolare.
Block Cipher vs Stream Cipher#

Block cipher — cifra i dati in blocchi di dimensione fissa (es. 64 bit o 128 bit). Divide file o messaggi grandi in blocchi e cifra ogni blocco separatamente. Piu' efficiente quando la dimensione del dato e' nota (es. file, campo di database).
Stream cipher — cifra i dati come flusso di bit o byte, uno alla volta. Non divide in blocchi. Piu' efficiente quando la dimensione e' sconosciuta o il dato arriva come stream continuo (es. audio e video in streaming su rete).
I key non devono mai essere riusati in uno stream cipher. Se una chiave viene riusata, la cifratura e' piu' facile da craccare.
Block cipher: | blocco 1 | blocco 2 | blocco 3 | ...
ogni blocco cifrato separatamente con la stessa chiave
Stream cipher: bit 1, bit 2, bit 3, bit 4, ...
ogni bit (o byte) cifrato in sequenza continuaStream cipher = cifra un singolo bit (o byte) alla volta, in flusso. Block cipher = cifra in blocchi di dimensione fissa (64 o 128 bit). Stream cipher e' piu' efficiente per dati in stream continuo. Block cipher e' piu' efficiente per dati di dimensione nota.
Dev parallel: Node.js
crypto.createCipheriv('aes-256-cbc', key, iv)usa AES, un block cipher simmetrico. La stessa chiave cifra e decifra. Per scambiare quella chiave in modo sicuro tra due parti si usa crittografia asimmetrica (es. TLS handshake). L'IV (Initialization Vector) garantisce che lo stesso plaintext cifrato due volte produca ciphertext diversi.
Symmetric = stessa chiave per cifrare e decifrare. Secret-key encryption e session-key encryption sono sinonimi. AES usa tipicamente 128 bit (supporta anche 192/256). Il rischio del riuso della chiave: se crackato, tutti i dati cifrati con quella chiave sono esposti.
Common Symmetric Algorithms#
AES#
L'Advanced Encryption Standard (AES) e' un block cipher simmetrico adottato dal NIST6 dal Rijndael encryption algorithm dopo una lunga valutazione.
AES cifra i dati in blocchi da 128 bit (fissi). Supporta tre key size: 128, 192 o 256 bit.
| Block size | Key size | Round interni | |
|---|---|---|---|
| AES-128 | 128 bit (fisso) | 128 bit | 10 |
| AES-192 | 128 bit (fisso) | 192 bit | 12 |
| AES-256 | 128 bit (fisso) | 256 bit | 14 |
Il numero nel nome (AES-128, AES-256) identifica la chiave, non il blocco. Il blocco e' sempre 128 bit.
Chiave piu' grande = piu' combinazioni possibili = piu' difficile da forzare:
AES-128: 2^128 chiavi possibili ~ 340 undecilioni
AES-256: 2^256 chiavi possibili ~ il quadrato di AES-128AES aumenta anche il numero di round interni all'aumentare della chiave: il blocco da 128 bit viene rimescolato piu' volte. Per un utente la differenza di velocita' e' impercettibile. AES-128 e' gia' computazionalmente inattaccabile oggi. AES-256 e' scelto per protezione contro hardware futuro (computer quantistici).
Punti di forza di AES:
- Fast: un solo pass per cifrare e decifrare (a differenza di 3DES che richiede piu' pass). Un pass = una singola applicazione completa dell'algoritmo sul blocco. AES cifra ogni blocco in un unico passaggio (10/12/14 round interni). 3DES applica DES tre volte di fila sullo stesso blocco = tre pass = tre volte piu' lento.
- Efficient: meno resource-intensive di 3DES, funziona bene anche su dispositivi piccoli (USB flash drive)
- Strong: alto livello di confidenzialita'
Pass vs Round
| Termine | Livello | Significato |
|---|---|---|
| Pass | Alto | Un'intera esecuzione dell'algoritmo sul blocco dall'inizio alla fine |
| Round | Basso | Un singolo step interno dentro quel passaggio |
AES: 1 pass, con 10/12/14 round interni (SubBytes, ShiftRows, MixColumns, AddRoundKey). 3DES: 3 pass = DES completo eseguito tre volte. Ogni DES ha 16 round interni → 3 × 16 = 48 round totali. La lentezza deriva dal numero di pass, non dai round.
Dev parallel:
crypto.createCipheriv('aes-256-cbc', key, iv)in Node.js usa AES-256 (chiave 256 bit, blocco 128 bit). L'IV (Initialization Vector) garantisce che lo stesso plaintext cifrato due volte produca ciphertext diversi.
AES block size = sempre 128 bit. AES-128/192/256 = key size, non block size. Chiave piu' lunga = piu' round = piu' sicuro. AES-256 usato quando si vuole resistenza ai computer quantistici.
3DES#
Il 3DES (Triple DES) e' un block cipher simmetrico nato come miglioramento rispetto alle debolezze note del DES (Data Encryption Standard) originale.
Funzionamento: applica l'algoritmo DES tre volte in pass separati su ogni blocco, usando chiavi multiple.
| AES | 3DES | |
|---|---|---|
| Block size | 128 bit | 64 bit |
| Key size | 128 / 192 / 256 bit | 112 o 168 bit |
| Pass | 1 | 3 |
| Velocita' | Veloce | Lento (3x DES) |
| Uso oggi | Standard | Solo se hardware non supporta AES |
3DES e' un algoritmo robusto ma non piu' la prima scelta: AES e' molto meno resource-intensive. Viene usato come alternativa quando l'hardware non supporta AES nativamente.
3DES block size = 64 bit (non 128 come AES). Key size = 112 o 168 bit. Tre pass = tre volte piu' lento di DES. Usato solo quando AES non e' disponibile.
Blowfish and Twofish#
Blowfish e' un block cipher simmetrico ancora ampiamente usato, progettato da Bruce Schneier7 come algoritmo general-purpose in sostituzione di DES.
- Block size: 64 bit
- Key size: da 32 a 448 bit (range molto ampio)
- In alcuni casi piu' veloce di AES, specialmente vs AES-256, perche' cifra blocchi piu' piccoli (64 vs 128 bit)
Twofish e' correlato a Blowfish ma con caratteristiche diverse:
- Block size: 128 bit (come AES)
- Key size: 128, 192 o 256 bit (come AES)
- E' stato uno dei finalisti nella competizione NIST che ha selezionato AES
Confronto algoritmi simmetrici — riepilogo
| Algoritmo | Block size | Key size | Note |
|---|---|---|---|
| AES | 128 bit | 128 / 192 / 256 bit | Standard attuale NIST |
| 3DES | 64 bit | 112 / 168 bit | Legacy, 3 pass |
| Blowfish | 64 bit | 32-448 bit | Veloce, general-purpose |
| Twofish | 128 bit | 128 / 192 / 256 bit | Finalista NIST, non selezionato |
AES: block 128 bit, key 128/192/256 bit, standard NIST attuale. 3DES: block 64 bit, key 112/168 bit, legacy — usato solo se hardware non supporta AES. Blowfish: block 64 bit, key 32-448 bit. Twofish: block 128 bit, finalista NIST non selezionato.
Asymmetric Encryption#
La asymmetric encryption usa due chiavi abbinate per cifrare e decifrare: una public key e una private key.
Regole fondamentali:
- Public key cifra → solo la private key abbinata decifra
- Private key cifra → solo la public key abbinata decifra
- La private key e' sempre tenuta privata, mai condivisa
- La public key e' distribuita liberamente, incorporata in un certificato digitale condiviso
Sono matematicamente simmetriche ma semanticamente diverse:
- Public key cifra = confidenzialita' (solo il destinatario con la private key legge)
- Private key cifra = autenticazione / firma digitale (chiunque puo' verificare con la public key, ma solo il titolare della private key poteva produrre quella firma)
"Cifrare con la private key" non protegge la riservatezza — la protegge la public key. La private key serve per dimostrare identita'. Questa e' la base della firma digitale. Vedi #Regola fondamentale della crittografia asimmetrica e approfondimento: La firma digitale.
Il pattern completo — confidenzialita' + autenticazione insieme:
Mittente:
1. Cifra il messaggio con la PUBLIC KEY del destinatario → confidenzialita'
2. Calcola il digest (hash) del messaggio
3. Firma il digest con la propria PRIVATE KEY → autenticazione
Invia: messaggio cifrato + firma digitale
Destinatario:
1. Decifra il messaggio con la propria PRIVATE KEY → legge il contenuto
2. Verifica la firma con la PUBLIC KEY del mittente → ottiene il digest originale
3. Ricalcola il digest del messaggio ricevuto e confronta → verifica integrita' e identita'Risultato: confidenzialita' + autenticazione + integrita' + non-repudiation in un'unica operazione. Questo e' il meccanismo alla base di S/MIME e PGP.
Asimmetrica e' piu' sicura ma molto piu' resource-intensive della simmetrica: richiede significativa potenza di calcolo per cifrare e decifrare. Per questo la maggior parte dei protocolli crittografici la usa solo per il key exchange, non per cifrare l'intero traffico.
Pattern ibrido tipico (es. TLS):
1. Asymmetric → scambia la session key (costoso, fatto una volta sola)
2. Symmetric → cifra tutto il traffico con quella session key (veloce)| Symmetric | Asymmetric | |
|---|---|---|
| Chiavi | 1 (stessa per cifrare e decifrare) | 2 (public + private) |
| Velocita' | Veloce | Lenta |
| Uso tipico | Cifrare i dati | Key exchange |
| Problema | Come distribuire la chiave? | Risolto: la public key si condivide liberamente |
Regola fondamentale della crittografia asimmetrica#
Cifrato con PUBLIC KEY -> decifrato SOLO con PRIVATE KEY
Cifrato con PRIVATE KEY -> decifrato SOLO con PUBLIC KEYQuesta regola non e' simmetrica nell'uso: cifrare con la public key = confidenzialita'. Cifrare con la private key = autenticazione (digital signature). Sono due operazioni distinte con scopi opposti.
| Operazione | Chi cifra | Chi decifra / verifica | Servizio |
|---|---|---|---|
| Encryption | Public key | Private key | Confidenzialita' |
| Firma digitale | Private key (firma il digest) | Public key (verifica) | Autenticita' + Integrita' + Non-repudiation |
L'integrita' nella firma digitale viene dall'hash incluso nella firma: se il messaggio viene modificato in transito, l'hash ricalcolato dal ricevente non combacia con quello nella firma. Non e' la public/private key a garantire l'integrita' — e' l'hash.
Cosa succede se si perde la private key — analisi CIA
Il risultato dipende da come si "perde":
| CIA | Chiave persa (nessuno ce l'ha) | Chiave compromessa (rubata) |
|---|---|---|
| Confidentiality | Mantenuta verso l'esterno — nessuno decifra. Tu nemmeno. | Violata — l'attaccante decifra tutto il traffico cifrato con la tua public key |
| Integrity | Firme esistenti ancora verificabili. Nuove firme: impossibile. | Violata — l'attaccante puo' firmare messaggi a tuo nome |
| Availability | Impatto massimo — tutto il dato cifrato e' inaccessibile per sempre | Mantenuta per te, ma il sistema non e' piu' fidato |
Perdere = problema di availability. Rubare = problema di confidentiality + integrity.
Per questo esiste il key escrow: una copia della chiave in custodia sicura per il recovery — vedi #Key Escrow.
Key Exchange#
Il key exchange e' il metodo crittografico con cui due entita' si scambiano chiavi crittografiche. In questo contesto: la crittografia asimmetrica viene usata per scambiare una chiave simmetrica. Poi e' la crittografia simmetrica a cifrare il traffico effettivo, perche' e' molto piu' efficiente.
Il problema da risolvere: le due entita' devono concordare una symmetric key che entrambe conoscono, ma lo scambio deve essere cifrato in modo che nessun terzo la conosca.
Soluzione:
1. Bob genera una symmetric key
2. Bob cifra la symmetric key con la PUBLIC KEY di Alice <- asimmetrica
3. Alice decifra con la sua PRIVATE KEY <- asimmetrica
4. Ora entrambi hanno la symmetric key
5. Tutto il traffico successivo viene cifrato con essa <- simmetrica (veloce)Questo e' il pattern ibrido: asimmetrica per il key exchange (costoso, una volta sola), simmetrica per i dati (veloce, per tutta la sessione). TLS usa esattamente questo meccanismo — vedi #Encrypting HTTPS Traffic with TLS.
Key exchange = usare la crittografia asimmetrica per consegnare una chiave simmetrica. L'asimmetrica non cifra i dati — prepara il terreno per la simmetrica che li cifra.
Pattern ibrido: asymmetric + symmetric
sequenceDiagram
participant C as Client
participant S as Server
Note over S: Ha una coppia di chiavi:
PUBLIC KEY (condivisa)
PRIVATE KEY (segreta)
S->>C: Invia PUBLIC KEY (nel certificato)
Note over C: Genera una session key simmetrica casuale
C->>C: Cifra session key con PUBLIC KEY del server
C->>S: Invia session key cifrata
Note over S: Decifra con PRIVATE KEY → ottiene session key
Note over C,S: Entrambi hanno la STESSA session key simmetrica
Note over C: Cifra con session key (AES)
C->>S: Dati cifrati → AES encrypt(session key, dati)
Note over S: Decifra con session key (AES)
Note over S: Cifra risposta con session key (AES)
S->>C: Risposta cifrata → AES encrypt(session key, risposta)
Note over C: Decifra con session key (AES)
TLS 1.3 e le chiavi effimere (ECDHE)
TLS 1.3 non trasmette mai la session key — la fa derivare indipendentemente a entrambi i lati usando Diffie-Hellman efimero:
sequenceDiagram
participant C as Client
participant S as Server
C->>S: Client Hello + chiave pubblica EFFIMERA del client
S->>C: Server Hello + chiave pubblica EFFIMERA del server + certificato
Note over C: Combina propria chiave privata effimera
+ chiave pubblica effimera del server
→ deriva session key
Note over S: Combina propria chiave privata effimera
+ chiave pubblica effimera del client
→ deriva la STESSA session key
Note over C,S: Stessa session key, mai trasmessa
C->>S: Dati cifrati (AES)
S->>C: Risposta cifrata (AES)
"Effimero" significa che le chiavi DH vengono generate per ogni sessione e poi scartate. Anche se in futuro qualcuno ruba la private key del server, non puo' decifrare le sessioni passate perche' le chiavi effimere non esistono piu'. Questa proprieta' si chiama Perfect Forward Secrecy (PFS).
Dev parallel: quando vedi
ECDHEin una cipher suite TLS (es.TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) — quella E finale sta per Ephemeral. Senza la E (es.TLS_RSA_WITH_AES_256_CBC_SHA) non c'e' PFS: se la private key del server viene rubata, tutto il traffico passato e' decifrabile.
The Raybern Box#
Il Rayburn box e' una metafora di Gibson (Rayburn e' il suo secondo nome — non esiste nella realta') per rendere visivo il funzionamento delle chiavi asimmetriche. E' una cassetta di sicurezza con due chiavi abbinate:
- Chiave 1 — puo' solo chiudere, non aprire → analogia: public key, copie multiple distribuite liberamente
- Chiave 2 — puo' solo aprire, non chiudere → analogia: private key, una sola copia, sempre privata
Le due chiavi sono abbinate a quella cassetta e non funzionano con altre cassette.
sequenceDiagram
participant M as Mittente
participant R as Ricevente
rect rgba(50, 120, 220, 0.2)
Note over M,R: VERSIONE 1 — CONFIDENZIALITA'
R->>M: Cassetta vuota + copia PUBLIC KEY (chiude ma non apre)
Note over M: Inserisce il contenuto
M->>M: Chiude con PUBLIC KEY
M->>R: Spedisce cassetta chiusa
Note over R: Apre con PRIVATE KEY (unica copia)
Note over M,R: Chi ha copie della public key non puo' aprire
end
rect rgba(50, 180, 80, 0.2)
Note over M,R: VERSIONE 2 — AUTENTICAZIONE
Note over M: Inserisce il messaggio
M->>M: Chiude con PRIVATE KEY
M->>R: Spedisce cassetta chiusa
R->>R: Apre con PUBLIC KEY
Note over R: Si apre con public key = M l'ha chiusa = M ha inviato
Note over M,R: Spia apre con public key ma non puo' richiudere
end
Versione 1 — Confidenzialita'
Il ricevente manda la cassetta vuota aperta insieme a copie della public key. Il mittente ci mette il contenuto e chiude con la public key. Solo la private key (una sola, mai condivisa) puo' aprire. Anche chi ha copie della public key non puo' riaprire la cassetta.
Versione 2 — Autenticazione
Il mittente chiude la cassetta con la propria private key. Chiunque abbia la public key puo' aprirla — ma questa e' la prova: se si apre con la mia public key, significa che e' stata chiusa con la mia private key, quindi sono io ad averla inviata. Una spia che intercetta puo' aprirla ma non richiuderla: il ricevente riceve una cassetta aperta e sa che il messaggio e' stato manomesso.
Solo la private key decifra cio' che e' stato cifrato con la matching public key. Solo la public key decifra cio' che e' stato cifrato con la matching private key. Diversi metodi di asymmetric encryption richiedono un certificato digitale e una PKI.
Certificates#


"Un certificato digitale e' un contenitore per la public key" — FALSO. Un contenitore non prova nulla. Il valore del certificato sta nella firma della CA che associa quella chiave a quell'identita'. Senza la firma, chiunque potrebbe creare un "contenitore" con la chiave che vuole.
flowchart TD
CA["CA
Certificate Authority"]
CERT["Certificato Digitale
Serial Number · Issuer
Validity dates · Subject
Public Key · Key Usage
Firma della CA"]
OWNER["Proprietario
ha la private key"]
USER["Chiunque
riceve il certificato"]
CA -->|"emette e firma"| CERT
OWNER -->|"condivide"| CERT
CERT -->|"distribuito a"| USER
USER -->|"usa la public key per cifrare o verificare"| OWNER
Elementi comuni di un certificato digitale
| Campo | Contenuto |
|---|---|
| Serial Number | Identificativo unico per la CA emittente. Usato per validare e revocare (pubblicato nel CRL se revocato) |
| Issuer | La CA che ha emesso il certificato |
| Validity dates | "Valid From" e "Valid To" — date di validita' e scadenza |
| Subject | Il proprietario del certificato (es. Google, Inc) |
| Public Key | La chiave pubblica del proprietario |
| Key Usage | Per cosa e' valido: solo encryption, solo authentication, o entrambi |
Certificate Attributes — Distinguished Name
| Attributo | Espansione | Esempio |
|---|---|---|
| CN | Common Name (FQDN) | letsencrypt.org |
| O | Organization | Internet Security Research Group |
| L | Locality | Mountain View |
| S | State or Province | CA |
| C | Country | US |
I certificati digitali contengono la public key + dettagli sul proprietario + dettagli sulla CA emittente. Il proprietario condivide la public key condividendo il certificato. Mai la private key.
Perche' non basta condividere la public key direttamente?
Il problema non e' avere la public key — e' sapere a chi appartiene.
Senza certificato:
Alice invia a Bob la sua public key
Charlie intercetta e SOSTITUISCE la chiave di Alice con la SUA prima che arrivi a Bob
Bob riceve la chiave di Charlie credendo sia quella di Alice
Bob cifra con la chiave di Charlie → Charlie decifra tutto
Alice non riceve niente di sensato → MITM perfetto, invisibile a BobL'attacco non e' "intercettare il traffico cifrato" (che sarebbe inutile senza la chiave). L'attacco e' sostituire la chiave prima che venga usata — nel momento in cui Alice la spedisce. Bob non si accorge perche' una public key e' solo un numero: non contiene informazioni su chi la possiede. La chiave di Charlie sembra identica, strutturalmente, alla chiave di Alice.
Il certificato risolve questo legando public key + identita' + firma di una CA fidata:
Certificato = public key
+ "questa chiave appartiene a google.com"
+ firma digitale della CAQuando ricevi il certificato di Google:
- Leggi: "questa public key appartiene a google.com"
- Verifichi la firma della CA → la CA ha attestato questa associazione
- Il tuo browser si fida della CA perche' e' nel trust store del sistema operativo
Charlie non puo' falsificare questo: non ha la private key della CA, quindi non puo' produrre una firma valida.
Il certificato non e' "un contenitore per la public key" — e' una dichiarazione firmata da un'autorita' fidata che associa quella chiave a quella identita'. Senza questo, l'asymmetric encryption e' vulnerabile al MITM.
PKI = fiducia centralizzata
La PKI9 (Public Key Infrastructure) e' esattamente questo meccanismo: un sistema gerarchico in cui la fiducia parte da un'autorita' centrale (la CA root) e si propaga verso il basso.
Quando navighi su google.com, non ti chiedi "questa chiave e' di Google?" — ti chiedi "mi fido della CA che ha firmato questo certificato?". Il tuo sistema operativo contiene gia' ~150 CA pre-approvate da Microsoft, Apple, Mozilla. Ti sei fidato di loro per default, senza averle scelte esplicitamente.
flowchart TD
OS["Sistema Operativo
(Windows / macOS / Linux)
trust store con ~150 CA pre-installate"]
ROOT["CA Root
DigiCert, Let's Encrypt, Comodo...
chiave privata tenuta offline"]
INTER["CA Intermedia
emette certificati per i siti"]
CERT["Certificato google.com
public key + identita'
firmato dalla CA Intermedia"]
BROWSER["Il tuo browser
verifica la catena di fiducia"]
OS -->|"si fida di"| ROOT
ROOT -->|"firma"| INTER
INTER -->|"emette e firma"| CERT
BROWSER -->|"riceve"| CERT
BROWSER -->|"risale la catena fino alla CA Root"| ROOT
ROOT -->|"trovata nel trust store"| BROWSER
Questa struttura si chiama chain of trust: ogni anello e' firmato dall'anello superiore. Se la catena porta a una CA Root nel trust store → connessione fidata.
Il rischio del modello centralizzato: DigiNotar (2011)
Se una CA viene compromessa, tutti i certificati che ha emesso diventano inaffidabili. Nel 2011 la CA olandese DigiNotar fu violata: gli attaccanti emisero certificati falsi per google.com, CIA, Mossad e altri. Qualsiasi browser si fidava di DigiNotar accettava quei certificati come legittimi. Quando la compromissione fu scoperta, DigiNotar fu rimossa dal trust store di tutti i browser in giorni. L'azienda falli' settimane dopo.
La PKI sposta il problema di fiducia dalla singola chiave alla CA. E' un compromesso deliberato: scala per miliardi di connessioni HTTPS, ma crea un single point of failure. Se la CA e' compromessa, lo sono anche tutti i suoi certificati.
Cosa significa PKI — Public Key Infrastructure
- Public Key = il meccanismo su cui si basa (chiavi asimmetriche)
- Infrastructure = non e' un singolo algoritmo o protocollo — e' un sistema completo
La I di Infrastructure e' il punto chiave: enfatizza che PKI e' tutto l'ecosistema che gestisce l'intero ciclo di vita delle chiavi pubbliche:
| Fase | Cosa copre la PKI |
|---|---|
| Creare | Chi genera le chiavi, con quale algoritmo, con quale lunghezza |
| Distribuire | Certificati, CA, come arriva la public key a chi ne ha bisogno |
| Verificare | Chain of trust, trust store, validazione del certificato |
| Revocare | CRL (Certificate Revocation List), OCSP — quando un certificato non e' piu' valido |
| Rinnovare | Scadenza, reissuance, aggiornamento delle chiavi |
Non si chiama "Public Key System" o "Public Key Protocol" perche' non e' una cosa sola. La CA, il certificato, il trust store del browser, la CRL, le policy di revoca: tutto insieme e' la PKI. I certificati sono uno degli strumenti dell'infrastruttura, non l'infrastruttura in se'.
La CA non risolve la cifratura — AES e RSA funzionano anche senza di essa. La CA risolve il binding chiave-identita': la certezza che la public key con cui cifri appartenga davvero al destinatario corretto e non a un attaccante nel mezzo.
Public key da sola = numero anonimo (non sai di chi e')
Public key + CA = numero con identita' verificata da un terzo fidatoSenza CA sai cosa e' la chiave. Con la CA sai di chi e'.
CA in azione — visita a un sito HTTPS passo per passo
Il trust store e' un archivio di CA fidate pre-installato sul tuo sistema operativo dal produttore:
- macOS: Keychain Access → Certificati di sistema (~170 CA)
- Windows: Certificate Manager (
certmgr.msc) → Trusted Root Certification Authorities - Linux:
/etc/ssl/certs/o pacchettoca-certificates - Server (Ubuntu, nginx, Apache): stesso identico meccanismo — quando il server fa richieste HTTPS in uscita (es. chiama un'API esterna), usa il suo trust store per verificare il certificato remoto. Un server e' sia "server" per i suoi client che "client" verso i servizi che contatta.
Apple, Microsoft e le distro Linux decidono quali CA includere. Puoi aggiungere CA personalizzate (es. una CA interna aziendale) o rimuoverne.
sequenceDiagram
participant B as Browser (su macOS/Windows/Linux)
participant S as Server google.com
participant TS as Trust Store
(Keychain / certmgr / ca-certificates)
B->>S: 1. Connessione HTTPS
S->>B: 2. Invia certificato
(public key + identita' + firma DigiCert)
Note over B: 3. "Firmato da DigiCert"
B->>TS: 4. DigiCert e' nel trust store?
TS->>B: 5. Si' — CA fidata
Note over B: 6. Verifica firma DigiCert
Il trust store contiene la PUBLIC KEY di DigiCert
Browser: ricalcola hash dei dati del certificato
Browser: verifica la firma con PUBLIC KEY DigiCert → hash originale
I due hash coincidono = DigiCert ha firmato = certificato autentico
Note over B: 7. Estrae public key di google.com
B->>S: 8. Key exchange con public key di google.com
Note over B,S: 9. Session key → traffico cifrato AES
La CA non partecipa alla connessione in tempo reale — ha firmato il certificato in anticipo. Il browser verifica la firma offline, usando la public key della CA gia' presente nel trust store. DigiCert non viene mai contattata durante la tua navigazione.
"Il browser contatta DigiCert per verificare il certificato" — FALSO. La verifica e' completamente locale: il browser prende la public key di DigiCert dal trust store, ricalcola l'hash del certificato e confronta la firma. Nessuna richiesta di rete verso DigiCert.
L'unica cosa che potrebbe coinvolgere DigiCert e' la verifica di revoca via OCSP (se il certificato e' stato revocato prima della scadenza) — ma e' un controllo separato, opzionale, e non e' la "verifica del certificato".
Non solo siti web — la PKI si usa ovunque:
| Contesto | Cosa viene autenticato |
|---|---|
| HTTPS | Identita' del server web |
| S/MIME | Identita' del mittente email |
| Code signing | Identita' del publisher del software |
| VPN | Identita' del client/server VPN |
| Smart card aziendale | Identita' del dipendente |
| IoT / dispositivi di rete | Identita' del device |
| SSH certificates | Identita' del server o utente SSH |
Il meccanismo e' sempre lo stesso: una CA firma il binding "questa chiave appartiene a questa entita'", chiunque si fida della CA puo' verificarlo.
Le CA servono solo per le email? Solo per l'HTTPS?
Le CA servono in ogni scenario dove devi fidarti di una public key di qualcuno che non hai mai incontrato di persona. Il MITM e' la minaccia concreta, ma il problema fondamentale e': "questa public key e' davvero di Google / di Lisa / del server VPN?". La CA certifica quella risposta.
| Scenario | CA serve? | Senza CA il rischio e' |
|---|---|---|
| HTTPS | Si' | Charlie sostituisce la public key del server |
| Email firmata (S/MIME) | Si' | Charlie sostituisce il .p7s con la sua chiave |
| Email cifrata | Si' | Come sai che stai cifrando con la public key giusta? |
| Code signing | Si' | Charlie firma malware spacciandolo per Microsoft |
| VPN con certificati | Si' | Stesso problema di autenticazione |
| SSH | No (TOFU) | Trust al primo collegamento, poi pinnata in known_hosts |
| PGP/GPG | No (web of trust) | Gli utenti si firmano le chiavi a vicenda |
SSH e' l'eccezione storica: non usa CA, usa TOFU (Trust On First Use) — accetti la chiave al primo collegamento, poi se cambia SSH ti avverte. Funziona perche' tipicamente conosci gia' il server che stai raggiungendo.
PGP/GPG — Web of Trust: come funziona davvero
Nel modello PGP non esiste nessuna CA centrale. La fiducia e' distribuita tra gli utenti stessi: tu firmi la chiave di qualcuno dopo averlo verificato di persona.
Alice conosce Bob di persona → verifica il suo documento →
firma la public key di Bob con la propria private key →
pubblica la firma su un keyserver insieme alla chiave di BobQuando scarichi la chiave di Bob, vedi anche le firme. Se trovi la firma di Alice, e tu ti fidi di Alice, hai un motivo transitivo per fidarti che quella chiave e' davvero di Bob.
La fiducia si propaga come un grafo:
Tu → ti fidi di Alice
Alice → ha firmato la chiave di Bob
Bob → ha firmato la chiave di Charlie
→ hai un percorso di fiducia fino a Charlie senza averlo mai incontratoKey signing party — eventi reali dove i partecipanti si trovano fisicamente, mostrano un documento d'identita' e firmano le chiavi a vicenda. Piu' firme riceve una chiave da persone gia' fidate, piu' e' considerata autentica. La fiducia parte dal mondo fisico, non da un'autorita'.
Perche' internet ha scelto le CA invece del web of trust:
Il web of trust non scala. Per mandare un'email cifrata a google.com dovresti conoscere qualcuno che conosce qualcuno di Google. Le CA risolvono questo con un'autorita' centrale pre-fidata da tutti — meno elegante, ma funziona per miliardi di connessioni verso server che non hai mai incontrato.
Riassunto: CA = soluzione al problema "a chi appartiene questa public key?". Il MITM e' la conseguenza di non averle. Non e' solo email — e' qualsiasi contesto con crittografia asimmetrica verso qualcuno che non hai mai incontrato di persona.
Chi decide quali CA sono attendibili?
I produttori di OS e browser — ognuno gestisce il proprio programma di inclusione:
| Programma | Gestito da | Copre |
|---|---|---|
| Apple Root Program | Apple | macOS, iOS, Safari — Safari usa il trust store di macOS, non ha il suo |
| Microsoft Root Program | Microsoft | Windows, Edge |
| Mozilla Root Program | Mozilla | Firefox — trust store completamente indipendente dall'OS, gestito da Mozilla |
| Google Root Program | Android, Chrome |
Per essere inclusa una CA deve superare audit annuali indipendenti (standard WebTrust o ETSI). Il CA/Browser Forum e' il tavolo dove CA e browser vendor concordano le regole comuni.
Se cancelli tutte le CA dal trust store:
Ogni sito HTTPS mostra errore — il browser non riesce a verificare nessun certificato. E' esattamente quello che fanno le aziende con l'SSL inspection: rimuovono tutte le CA pubbliche e installano solo la CA interna aziendale. Tutto il traffico HTTPS passa da un proxy che decifra, ispeziona e ricifra. I dipendenti hanno solo la CA aziendale nel trust store — il proxy gestisce la fiducia verso l'esterno per conto loro.
Il motivo non e' "ridurre la superficie di attacco" in senso generico — e' ispezionare il contenuto cifrato: DLP (data loss prevention), antivirus sul traffico web, blocco di siti vietati, logging di tutto. Senza SSL inspection, il traffico HTTPS e' opaco al firewall aziendale — vede solo che il dipendente e' su gmail.com, non cosa scrive.
CA nuove — processo lento per design:
CA nuova → richiesta inclusione → audit WebTrust/ETSI
→ revisione pubblica (mesi) → voto browser vendor
→ inclusione nel prossimo aggiornamento OS/browserLet's Encrypt e' stata fondata nel 2014 e inclusa nei trust store nel 2016 — due anni. La lentezza e' deliberata: una CA inclusa e' fidata da miliardi di dispositivi. Un errore di valutazione ha conseguenze globali.
Ephemeral Keys#
Ephemeral significa "che dura poco". In crittografia una ephemeral key ha vita breve: viene ricreata per ogni sessione e poi scartata. Al contrario una static key e' semipermanente — rimane la stessa per un lungo periodo.
| Ephemeral Key | Static Key | |
|---|---|---|
| Durata | Una singola sessione | Per tutta la vita del certificato (es. 1 anno) |
| Ricreata | Ad ogni connessione | Solo alla scadenza o rinnovo |
| Esempio | Chiavi DH in ECDHE | Chiave nel certificato TLS, chiave per firma digitale |
| CA puo' validarla? | No — troppo effimera | Si' — e' questo il punto dei certificati |
| Perfect Forward Secrecy | Si' | No |
Una ephemeral key pair include una chiave privata effimera e una chiave pubblica effimera. I sistemi usano questa coppia per una singola sessione e poi la scartano. Alcune versioni di Diffie-Hellman usano chiavi effimere — da qui l'acronimo ECDHE (Elliptic Curve Diffie-Hellman Ephemeral).
I certificati usano static key. Un certificato contiene una public key abbinata a una private key, e questa coppia e' valida per tutta la vita del certificato. I certificati hanno date di scadenza e i sistemi continuano a usare quelle chiavi finche' il certificato non scade. Un vantaggio delle static key: la CA puo' validarle — non puo' farlo con chiavi che vengono scartate ogni sessione.
Barno: "la static key e' la private key per le firme digitali classiche?" — esatto. Quando firmi un'email con S/MIME o quando un server autentica se stesso in TLS, usi la stessa chiave privata per tutta la vita del certificato. E' una static key. Il concetto si applica ovunque una firma deve essere verificabile nel tempo: la CA ha certificato quella chiave, chiunque puo' verificarla finche' il certificato e' valido.
flowchart TD
SK["Static Key
vive per la durata del certificato"]
EK["Ephemeral Key
vive per una singola sessione"]
SK --> SK1["Firma digitale (S/MIME, code signing)"]
SK --> SK2["Autenticazione server TLS
(firma le chiavi ECDHE)"]
SK --> SK3["Validabile dalla CA"]
EK --> EK1["Key exchange ECDHE"]
EK --> EK2["Perfect Forward Secrecy"]
EK --> EK3["Scartata dopo ogni sessione"]
Perfect Forward Secrecy e' la proprieta' chiave delle ephemeral key: il sistema genera chiavi pubbliche casuali per ogni sessione senza usare un algoritmo deterministico — dato lo stesso input, l'algoritmo produce una chiave pubblica diversa. Questo garantisce che i sistemi non riutilizzino mai le stesse chiavi. Il risultato: la compromissione di una chiave non compromette nessuna chiave passata.
Il ruolo del certificato in TLS 1.3: autenticazione, non cifratura
Domanda naturale a questo punto: "se il certificato contiene la public key di Google, perche' non uso quella per cifrare i miei dati direttamente?"
La risposta e' che esistono due modelli, uno vecchio e uno moderno:
| TLS 1.2 RSA (vecchio) | TLS 1.3 ECDHE (moderno) | |
|---|---|---|
| Come si scambia la session key | Browser cifra la session key con la public key del server e la manda | Browser e server derivano la session key con ECDHE — mai trasmessa |
| Chi cifra i dati | AES con la session key | AES con la session key |
| Ruolo della public key nel certificato | Usata per trasportare la session key | Usata per autenticare il server (firma le chiavi ECDHE effimere) |
| Se rubano la private key del server | Chiunque puo' decifrare tutto il traffico passato registrato | Il traffico passato e' al sicuro — le chiavi ECDHE effimere non esistono piu' |
| Perfect Forward Secrecy | No | Si' |
Il problema del modello RSA vecchio: chiunque registrasse traffico HTTPS oggi poteva aspettare di rubare la private key di Google domani e decifrare tutto retroattivamente. Con ECDHE le chiavi effimere vengono generate per la singola sessione e poi scartate — non ci sono chiavi da rubare in futuro.
Per quanto vive la private key di Google?
La private key puo' vivere anni — e' solo una coppia di numeri. Quello che scade e' il certificato (il documento firmato dalla CA che lega la chiave all'identita'):
Private key → puo' durare anni (Google la rigenera per scelta, non per obbligo)
Certificato → scade (90 giorni con Let's Encrypt, fino a 1 anno con altri)Alla scadenza del certificato, la CA firma un nuovo certificato — spesso con la stessa chiave, a volte con una nuova. Let's Encrypt rinnova automaticamente ogni 90 giorni. Google.com usa certificati a 90 giorni rinnovati in modo trasparente.
Il cerchio completo di una connessione HTTPS:
sequenceDiagram
participant CA as CA (DigiCert)
— offline —
participant B as Browser (Client)
participant G as google.com (Server)
Note over CA,G: Prima della connessione — fatto una volta sola
CA->>G: Firma il certificato con la CA private key
(lega public key di Google alla sua identita')
Note over B,G: Durante ogni connessione TLS 1.3
B->>G: 1. Client Hello + chiave pubblica ECDHE effimera del browser
G->>B: 2. Server Hello + chiave pubblica ECDHE effimera del server
+ Certificato (public key Google + firma DigiCert)
Note over B: 3. Verifica certificato
trust store → DigiCert presente → firma valida
→ questa chiave ECDHE e' davvero di Google
Note over B: 4. Deriva session key
propria chiave privata ECDHE effimera
+ public key ECDHE effimera del server
Note over G: 4. Deriva session key
propria chiave privata ECDHE effimera
+ public key ECDHE effimera del browser
Note over B,G: Stessa session key — mai trasmessa — chiavi ECDHE scartate
B->>G: 5. Traffico HTTP cifrato AES (session key)
G->>B: 5. Risposta cifrata AES (session key)
| Passo | Servizio | Chiave usata | Tipo |
|---|---|---|---|
| Firma certificato (offline) | Authentication | CA private key | Static |
| Verifica certificato | Authentication | CA public key (trust store) | Static |
| ECDHE key exchange | Key agreement | Chiavi DH effimere | Ephemeral |
| Session key | Confidentiality | Derivata matematicamente — mai trasmessa | Ephemeral |
| Traffico AES | Confidentiality | Session key simmetrica | Ephemeral |
La public key del certificato non cifra mai i tuoi dati. Autentica il server e garantisce che le chiavi ECDHE effimere siano davvero di Google e non di un MITM.
Rinnovo certificato — l'OS deve aggiornarsi?
No. Il trust store contiene le CA root, non le chiavi di Google. Google puo' rinnovare con la stessa chiave o generarne una nuova — l'OS non sa e non deve sapere. Fintanto che il nuovo certificato e' firmato da una CA gia' nel trust store, tutto funziona senza alcun aggiornamento lato client.
L'OS si aggiorna solo quando cambia una CA root: nuova CA inclusa, vecchia rimossa, o CA compromessa (DigiNotar 2011 → rimossa da tutti i trust store in giorni).
"La public key nel certificato viene usata per derivare le chiavi effimere" — impreciso. La public key del certificato non genera ne' deriva le chiavi ECDHE. Le chiavi ECDHE sono generate separatamente da entrambe le parti. La public key del certificato firma quelle chiavi effimere — autentica che appartengono al server legittimo. E' una firma di autenticazione, non un input alla derivazione.
Elliptic Curve Cryptography#
ECC (Elliptic Curve Cryptography) usa equazioni matematiche per formulare una curva ellittica, poi grafica punti sulla curva per creare le chiavi. Il vantaggio principale: le chiavi ECC possono essere molto piu' piccole rispetto alle chiavi non-ECC, con lo stesso livello di sicurezza, usando meno potenza di calcolo.
Equivalenza chiavi — meno bit, stessa sicurezza:
| Algoritmo | Dimensione chiave | Sicurezza equivalente |
|---|---|---|
| RSA / DSA | 3072 bit | 128-bit security |
| ECC / ECDSA | 256 bit | 128-bit security |
| RSA / DSA | 7680 bit | 192-bit security |
| ECC / ECDSA | 384 bit | 192-bit security |
Una chiave ECC a 256 bit offre la stessa sicurezza di una chiave DSA a 3072 bit — con 12x meno bit.
DSA vs ECDSA:
| DSA | ECDSA | |
|---|---|---|
| Espansione | Digital Signature Algorithm | Elliptic Curve DSA |
| Base matematica | Logaritmo discreto | Curva ellittica |
| Chiave per 128-bit security | 3072 bit | 256 bit |
| PKI / certificato | Si' | Si' |
| Uso tipico | Firma digitale (legacy) | Firma digitale moderna, TLS, Bitcoin |
flowchart TD
ECC["ECC
Elliptic Curve Cryptography"]
ECC --> ECDH["ECDHE
Key exchange in TLS 1.3
Perfect Forward Secrecy"]
ECC --> ECDSA["ECDSA
Digital Signature Algorithm
firma email, code signing, JWT"]
ECC --> BTC["Bitcoin / blockchain
curva secp256k1
chiavi wallet, firme transazioni"]
ECC --> IOT["Low-power devices
IoT, sensori, smart card
meno CPU richiesta"]
Caso d'uso principale: dispositivi a bassa potenza. ECC e' usata nei dispositivi wireless piccoli perche' richiede poca potenza di calcolo. Una smart card o un sensore IoT non hanno la CPU per fare RSA a 3072 bit — con ECC a 256 bit ottengono la stessa sicurezza.
Dev parallel: in Node.js quando generi un JWT hai due opzioni comuni —
RS256(RSA 2048 bit) oES256(ECDSA curva P-256). ES256 usa chiavi piu' piccole, firma piu' veloce, meno CPU. Lo vedi anche nei certificati TLS moderni:ECDHE_ECDSAnella cipher suite significa key exchange con ECDH effimero + firma con ECDSA.
Bitcoin usa ECC — precisamente la curva secp256k1. Il tuo indirizzo Bitcoin e' derivato dalla tua public key ECDSA. Quando firmi una transazione usi la tua private key ECDSA. E' la stessa matematica del TLS, su una curva diversa.
Domanda tipo: "quale algoritmo usa chiavi piu' piccole mantenendo lo stesso livello di sicurezza?" → ECC / ECDSA. "Quale variante di Diffie-Hellman garantisce Perfect Forward Secrecy?" → ECDHE (la E finale = Ephemeral).
Key Length#
L'algoritmo rimane sempre lo stesso — il modo per rafforzarlo e' aumentare la lunghezza della chiave. Chiave piu' lunga = piu' combinazioni possibili = piu' difficile da forzare con brute force.
RSA (Rivest-Shamir-Adleman) — il principale algoritmo di crittografia a chiave pubblica usato su Internet — supporta chiavi da 1024, 2048 e 4096 bit. NIST6 raccomanda di non usare piu' chiavi a 1024 bit per motivi di sicurezza. Il minimo raccomandato attuale e' 2048 bit.
Raccomandazioni NIST per lunghezza chiave:
| Algoritmo | Obsoleto | Minimo attuale | Consigliato |
|---|---|---|---|
| RSA / DSA | 1024 bit | 2048 bit | 3072 bit |
| ECC / ECDSA | 160 bit | 224 bit | 256 bit |
| AES (simmetrico) | DES 56 bit | 128 bit | 256 bit |
| SHA (hashing) | MD5, SHA-1 | SHA-256 | SHA-3-256 |
La relazione tra lunghezza chiave e sicurezza non e' lineare: raddoppiare i bit non raddoppia la difficolta' di attacco, la aumenta esponenzialmente. Da 1024 a 2048 bit RSA, il costo di un attacco brute force aumenta di miliardi di volte, non del doppio.
NIST minimum per RSA = 2048 bit. Chiavi RSA a 1024 bit = deprecate. Ricorda la proporzione ECC: 256 bit ECC ≈ 3072 bit RSA per sicurezza equivalente.
Obfuscation#
A volte non serve cifrare i dati — basta nasconderli in bella vista o rendere impossibile recuperare informazioni sensibili. L'obfuscation e' l'atto di rendere deliberatamente qualcosa poco chiaro, confuso o difficile da capire, per nascondere, distorcere o oscurare informazioni.
| Tecnica | Come nasconde | Cifra i dati? |
|---|---|---|
| Steganography | Nasconde dati dentro altri dati | No |
| Tokenization | Sostituisce dati sensibili con token | No (reversibile con vault) |
| Masking | Sostituisce parti del dato con caratteri neutri | No (irreversibile) |
Steganography#

I dati non sono cifrati ma nascosti. Non puo' essere classificata come simmetrica o asimmetrica. Puo' essere usata insieme alla crittografia per un doppio livello: prima cifri il messaggio, poi lo nascondi nell'immagine.
L'esempio piu' antico — Istieo di Mileto (~499 a.C.): Erodoto documenta il primo caso noto di steganografia. Istieo voleva inviare un messaggio segreto ad Aristagora per incitare la rivolta contro la Persia. Raso' la testa dello schiavo piu' fidato, tatuo' il messaggio sul cuoio capelluto, aspetto' che i capelli ricrescessero e lo mando' come messaggero. Aristagora doveva rasargli la testa per leggere. Il messaggio non era cifrato — chiunque lo avesse visto poteva leggerlo — ma era nascosto dove nessuno pensava di guardare. Stessa logica dei bit meno significativi di un JPEG.
Rilevamento — Steganalysis: Il metodo piu' comune e' l'hashing. Se anche un solo bit di un file viene modificato, l'hash cambia. Confrontando hash regolari degli stessi file, e' facile rilevare quando un file e' stato alterato per nascondere un messaggio.
Tre tipi principali di file:
Audio Steganography Sfrutta i limiti dell'orecchio umano: il range udibile e' 20 Hz — 20 kHz, ma la maggior parte degli umani non sente tra 18-20 kHz. I microfoni invece si'. Questi suoni, detti audio beacon, vengono usati per identificare l'attivita' degli utenti.
Caso reale — SilverPush:
Il setup:
- SilverPush era una societa' pubblicitaria indiana
- Le TV mandavano pubblicita' che contenevano suoni ad alta frequenza (18-20 kHz) — inudibili all'orecchio umano ma captabili dal microfono del telefono
- SilverPush distribuiva il suo SDK agli sviluppatori di app, che lo integravano silenziosamente
Il trucco: Le app con l'SDK ascoltavano costantemente il microfono in background. Quando captavano un beacon10 dalla TV, lo reportavano ai server SilverPush.
TV manda pubblicita' Coca-Cola → contiene beacon a 19kHz
Telefono in tasca → microfono capta il beacon
App con SDK SilverPush → "l'utente sta guardando lo spot Coca-Cola"
→ invia dato a SilverPush → SilverPush vende il dato agli advertiserRisultato: SilverPush sapeva esattamente quali spot e quali programmi guardavi — senza che tu lo sapessi, senza autorizzazione esplicita. Nel 2017 ricercatori trovarono oltre 200 app Android con questo SDK, scaricate milioni di volte da Google Play.
Uso in store: beacon audio tracciano la posizione dei clienti mentre si muovono nel negozio. Possono anche fare cross-device tracking: un dispositivo emette un beacon, quando un altro lo sente ripetutamente indica che appartengono allo stesso utente.
Image Steganography Due tecniche principali:
- Least Significant Bit (LSB): modifica il bit meno significativo di alcuni byte del file. Un pixel rosso RGB (255, 0, 0) diventa (254, 0, 0) — impercettibile a monitor. Con un file immagine grande si puo' nascondere un intero documento.
- White space: molti file hanno spazio inutilizzato alla fine dei cluster. Un file da 6 KB in due cluster da 4 KB ha 2 KB liberi — questo spazio puo' contenere un messaggio senza alterare la dimensione del file.
Come funziona il LSB tecnicamente:
Ogni file e' una sequenza di byte. Ogni byte = 8 bit. Il LSB e' l'ultimo — cambiarlo sposta il valore di al massimo 1 su 256, impercettibile.
Per nascondere la lettera "A" (ASCII 65 = 01000001) servono 8 byte del file — uno per ogni bit:
Byte file LSB originale LSB → bit di "A" Variazione
11001010 0 0 invariato
00110111 1 1 invariato
10110101 1 0 202 → 201
11001100 0 0 invariato
10101011 1 0 cambiato
00110100 0 0 invariato
11010110 0 0 invariato
10011001 1 1 invariato
↓
01000001 = "A" ricostruito leggendo i LSB in sequenzaIn Python:
with open('video.mp4', 'rb') as f:
data = bytearray(f.read())
secret = b'documenti segreti'
bits = ''.join(format(b, '08b') for b in secret)
for i, bit in enumerate(bits):
data[i] = (data[i] & 0xFE) | int(bit)
# 0xFE = 11111110 → azzera il LSB
# | int(bit) → imposta il LSB al bit del messaggio
with open('video_stego.mp4', 'wb') as f:
f.write(data)Capacita': 1GB di video = ~1 miliardo di byte → ~125MB nascondibili nei soli LSB. Usando 2-3 LSB per byte la capacita' triplica ma aumenta la distorsione.
Tool reali:
| Tool | Supporta |
|---|---|
steghide | Immagini, audio |
OpenPuff | Video, immagini, audio, PDF |
DeepSound | Audio |
zsteg | Analisi e estrazione da PNG/BMP |
Video Steganography Estensione dell'image steganography applicata ai video. I file video sono grandi — si modificano i bit meno significativi di alcuni byte. Attenzione: puo' causare rumore nella traccia audio. Per evitarlo, molti metodi modificano solo la parte immagine del video, lasciando intatta la traccia audio.
Facebook, YouTube e TikTok hanno reso i video enormemente popolari — grandi volumi di file video circolano liberamente senza destare sospetti. Questo li rende un covert channel ideale: caricare un video su YouTube e' traffico HTTPS normale, nessun firewall lo blocca, nessun IDS lo segnala.
Spia in azienda vuole esfiltrare 500MB di documenti
→ nasconde i file nei LSB di un video da 2GB
→ carica su YouTube come "video privato di vacanze"
→ complice scarica con youtube-dl
→ estrae i documenti nascosti
Firewall: ha visto solo HTTPS verso YouTube
DLP: nessun documento e' uscito in chiaro → nessun alertCasi reali documentati
IMAGE — i piu' documentati:
Turla APT (Russia, 2017) — documentato da ESET: I commenti sull'account Instagram di Britney Spears contenevano caratteri speciali nascosti che, decodificati, formavano l'indirizzo del server C2. Il malware sui PC infetti leggeva i commenti Instagram pubblicamente, estraeva l'indirizzo e si connetteva al server per ricevere istruzioni. Nessun traffico sospetto — era solo un browser che caricava Instagram.
Worok APT (2022) — documentato da ESET: Payload malware nascosto dentro file PNG distribuiti come allegati. La vittima apriva l'immagine, sembrava normale, ma dentro c'era il malware nei bit meno significativi.
AUDIO — air gap bypass:
MOSQUITO (2018) — ricercatori Universita' Ben-Gurion (Israele): Dimostrato che due computer air-gapped (senza connessione di rete) possono comunicare via ultrasuoni usando le casse come microfoni. Il malware su un laptop emetteva beacon a 19kHz — captati dallo smartphone vicino, connesso alla rete mobile, che trasmetteva i dati al C2. Il laptop non era connesso a internet, ma il canale audio aggirava il gap fisico.
Cosa si nasconde — riepilogo:
| Tipo | Cosa si nasconde | Caso reale |
|---|---|---|
| Image | Indirizzi C2, payload malware, chiavi | Turla APT (Instagram), Worok APT (PNG) |
| Video | Documenti esfiltrati, covert channel | Dimostrato da ricercatori |
| Audio | Comandi C2, bypass air gap | MOSQUITO — Ben-Gurion 2018 |
Steganography rileva modifica con hashing. Non cifra — nasconde. Tre tipi: audio, image, video. Audio beacon usati per tracking cross-device e air gap bypass.
Tokenization#
La tokenization sostituisce dati sensibili con placeholder non sensibili chiamati token. I token conservano le informazioni essenziali sul dato originale senza rivelarne il contenuto. Il dato originale e' conservato in un token vault separato che mappa ogni token al dato reale.
Usata per: payment processing, PII (Personally Identifiable Information), dati sanitari.
Esempio — carta di credito:
Dato reale: 4532 1234 5678 9012 ← mai toccato dal tuo sistema
Token: tok_8f3k2p9x1m ← quello che il tuo DB memorizza
Token vault (Stripe, Braintree):
tok_8f3k2p9x1m → 4532 1234 5678 9012Anche se il tuo DB viene compromesso, l'attaccante trova solo token — senza accesso al vault non puo' risalire ai numeri reali.
Dev parallel: quando integri Stripe non tocchi mai il numero della carta. Il form invia i dati direttamente a Stripe (non al tuo server), Stripe restituisce un token. Il tuo backend salva il token e lo usa per addebitare. L'hai quasi certamente gia' implementata senza saperlo.
Come funziona con Stripe — flusso completo:
sequenceDiagram
participant U as Utente (browser)
participant S as Il tuo server (ecommerce)
participant DB as Il tuo DB
participant ST as Stripe (token vault)
U->>ST: 1. Inserisce numero carta direttamente
nel form Stripe (Stripe.js)
ST->>U: 2. Restituisce token
tok_8f3k2p9x1m
U->>S: 3. Invia ordine + token
(MAI il numero carta)
S->>DB: 4. Salva ordine
user_id: 42, token: tok_8f3k2p9x1m
S->>ST: 5. "Addebita tok_8f3k2p9x1m di 50€"
Note over ST: Risolve token → 4532 1234 5678 9012
Esegue addebito
ST->>S: 6. Conferma pagamento
Note over DB: Il tuo DB contiene SOLO il token
Stripe e' l'unico che conosce la carta reale
Scenario attacco — perche' il token e' inutile:
Attaccante compromette il tuo DB
→ trova: user_id: 42, token: tok_8f3k2p9x1m
→ NON puo' risalire a 4532 1234 5678 9012 (vault e' da Stripe)
→ NON puo' clonare la carta
→ NON puo' venderla sul dark web come numero reale
→ L'unica cosa possibile: chiamare la tua API per addebitare
→ ma quella richiede le tue credenziali Stripe, non nel DBTokenization vs Encryption — differenza chiave:
| Tokenization | Encryption | |
|---|---|---|
| Relazione col dato | Nessuna (token casuale) | Matematica reversibile |
| Reversibile | Si', con accesso al vault | Si', con la chiave |
| Dato originale | Nel token vault separato | Ricavabile dalla chiave |
| Se rubano il DB | Token inutili senza vault | Ciphertext attaccabile offline |
Masking#
Il masking nasconde parzialmente o completamente dati sensibili sostituendoli con caratteri neutri (*, X, .). L'obiettivo e' impedire a utenti non autorizzati di vedere informazioni sensibili, mantenendo la funzionalita' per gli utenti autorizzati.
Usato per: display di dati a schermo, condivisione con terze parti, ambienti di sviluppo e test.
Esempi:
Numero conto: 123****1208 ← qualcuno guarda lo schermo → vede niente
Password field: •••••••• ← qualcuno guarda la tastiera → vede niente
Email: b***o@gmail.com ← log di sistema → PII non espostaMasking vs Tokenization — differenza chiave:
| Masking | Tokenization | |
|---|---|---|
| Scopo | Display — protezione visiva | Storage — protezione del dato |
| Originale conservato | Si' (la banca ha il tuo numero) | Si' (nel vault separato) |
| Reversibile | Solo da chi ha il dato originale | Si', tramite vault |
| Uso tipico | Mostrare dati a schermo | Sostituire dati nel DB |
Steganography, tokenization e masking sono tecniche di obfuscation per proteggere dati sensibili:
- Steganography: nasconde messaggi dentro altri file
- Tokenization: sostituisce dati sensibili con token non sensibili, conservando le info nel vault
- Masking: nasconde parzialmente o completamente dati sensibili con caratteri sostitutivi
Riepilogo obfuscation — tutti e tre:
| Tecnica | Cifra? | Reversibile? | Dato originale dove? | Caso d'uso |
|---|---|---|---|---|
| Steganography | No | Si' (se sai dove cercare) | Nel file stesso (LSB) | Covert channel, esfiltrazione |
| Tokenization | No | Si' (con vault) | Token vault separato | Pagamenti, PII nel DB |
| Masking | No | Solo dall'originale | Nel sistema sorgente | Display a schermo, log, test |
Using Cryptographic Protocols#
Con una comprensione di base di hashing, cifratura simmetrica e asimmetrica, e' piu' facile capire come la crittografia viene usata in pratica. Molte applicazioni usano una combinazione di questi metodi.
La domanda cardine: quale chiave cifra e quale decifra?
La risposta dipende da cosa vuoi ottenere:
| Scenario | Chi cifra | Con quale chiave | Chi decifra | Con quale chiave |
|---|---|---|---|---|
| Firma digitale email | Mittente | Propria private key | Destinatario | Public key del mittente |
| Cifratura email | Mittente | Public key del destinatario | Destinatario | Propria private key |
| HTTPS — key exchange | Browser | Public key del sito | Server | Propria private key |
| HTTPS — dati | Entrambi | Symmetric key (session key) | Entrambi | Stessa symmetric key |
flowchart TD
PK["Quale chiave sta cifrando?"]
PK -->|"PRIVATE key cifra"| DS["Digital Signature
authentication + non-repudiation"]
PK -->|"PUBLIC key cifra"| CONF["Confidentiality
solo il proprietario della private key puo' leggere"]
DS --> DS1["Email firma digitale
mittente firma con propria private key"]
CONF --> CONF1["Email cifrata
mittente cifra con public key del destinatario"]
CONF --> CONF2["HTTPS key exchange
browser cifra con public key del server"]
CONF --> CONF3["Session key AES
symmetric — stessa chiave per entrambi"]
Email e HTTPS usano una combinazione di asimmetrica + simmetrica: la crittografia asimmetrica scambia la chiave simmetrica in modo sicuro, la crittografia simmetrica cifra i dati.
Sapere quale chiave cifra e quale decifra aiuta a rispondere alle domande d'esame. Regola rapida: se una private key sta cifrando → e' una firma digitale.
Prima di entrare nei protocolli crittografici, i due servizi aggiuntivi che la crittografia puo' fornire:
Authentication: valida un'identita'. Non-repudiation: impedisce a una parte di negare di aver compiuto un'azione.
Il meccanismo che fornisce entrambi (piu' l'integrita') e' la firma digitale.
Digital Signature = hash del messaggio cifrato con la PRIVATE KEY del mittenteCome funziona una firma digitale:
Mittente:
1. Calcola hash del messaggio
2. Cifra l'hash con la propria PRIVATE KEY -> firma digitale
3. Invia messaggio + firma digitale
Destinatario:
1. Verifica la firma con la PUBLIC KEY del mittente -> hash originale
2. Calcola l'hash del messaggio ricevuto
3. Confronta i due hash -> se corrispondono: autenticita' + integrita' verificateSolo la public key del mittente puo' verificare la firma digitale. Questo prova che la firma e' stata creata con la private key del mittente. Risultato: authentication + non-repudiation + integrity in una sola operazione.
Protecting Email#
La crittografia offre due metodi di sicurezza per le email: firma digitale e cifratura. Sono processi separati ma possono essere usati insieme sulla stessa email.
Signing Emails with Digital Signatures#
La firma digitale e' un hash cifrato con la private key del mittente. Fornisce tre benefici di sicurezza:
| Beneficio | Cosa garantisce | Esempio |
|---|---|---|
| Authentication | Identifica il mittente — l'email viene da chi sembra | Un dirigente firma l'email → i destinatari sanno che non e' un attaccante che lo impersona |
| Non-repudiation | Il mittente non puo' negare di aver inviato il messaggio | Homer invia un ordine di vendita di azioni firmato digitalmente → se le azioni salgono dopo, non puo' negare la transazione |
| Integrity | Il messaggio non e' stato modificato | Hash del messaggio inviato = hash del messaggio ricevuto |
Il processo passo per passo (Lisa invia a Bart):
sequenceDiagram
participant L as Lisa (mittente)
participant B as Bart (destinatario)
Note over L: 1. Calcola hash del messaggio
Note over L: 2. Cifra l'hash con la propria PRIVATE KEY
→ firma digitale
L->>B: 3. Invia messaggio (in chiaro)
+ firma digitale
+ certificato di Lisa (.p7s allegato)
Note over B: 4. Estrae certificato dall'allegato .p7s
verifica firma CA sul certificato
→ estrae la PUBLIC KEY di Lisa
Note over B: 5. Verifica la firma con la PUBLIC KEY di Lisa
→ ottiene l'hash originale
Note over B: 6. Calcola l'hash del messaggio ricevuto
Note over B: 7. Confronta i due hash
alt Hash coincidono
Note over B: Authentication ✓ Non-repudiation ✓ Integrity ✓
else Hash diversi
Note over B: Errore firma digitale — messaggio alterato o mittente falso
end
Gibson usa "decifra la firma con la public key" riferendosi all'operazione matematica. Il termine corretto e' verifica. "Decifrare" implica confidentiality — rendere leggibile qualcosa di segreto. "Verificare" e' la parola giusta per le firme: controlli che la firma sia stata prodotta dalla private key corrispondente. Il messaggio era gia' in chiaro. Security+ usa "verify" per le firme, non "decrypt".
Il messaggio "I passed" non e' segreto — non e' cifrato. La firma digitale garantisce solo chi lo ha mandato e che non e' stato modificato. Se Lisa volesse anche nascondere il contenuto, dovrebbe cifrarlo separatamente.
Perche' firmiamo ma non sempre cifriamo?
Risorse. Cifrare 256 bit di un hash SHA-256 richiede pochissima potenza di calcolo. Cifrare un'email lunga con allegati richiederebbe molto di piu'. Se serve confidentiality si puo' cifrare, ma non sempre e' necessario.
Prerequisiti tecnici:
- Hashing: la firma parte da un hash del messaggio
- Certificato: contiene la public key del mittente — Bart recupera la public key di Lisa dal suo certificato
- Public/private key: Lisa usa la sua private key per firmare, Bart usa la public key di Lisa per verificare. La public key e' spesso distribuita in un file formato
S/MIME .p7s
Cos'e' il .p7s e come fa la CA a provare che la chiave e' di Lisa?
Il .p7s non e' solo la public key grezza — e' un contenitore strutturato che include la chiave, l'identita' e la firma della CA. Una public key grezza e' solo un numero: non dice nulla su chi la possiede. Charlie potrebbe intercettarla e sostituirla. Il .p7s risolve questo con la firma della CA che attesta il binding chiave-identita'.
Come la CA verifica l'identita' prima di firmare:
sequenceDiagram
participant L as Lisa
participant D as DigiCert (CA)
participant B as Bart
Note over L: 1. Genera key pair
private key + public key
L->>D: 2. Manda CSR (Certificate Signing Request)
contiene: public key + identita' + firma con propria private key
Note over D: 3. Verifica identita' di Lisa
manda email a lisa@azienda.com con sfida
Lisa risponde → prova che controlla quella casella
Note over D: 4. Crea il certificato
public key Lisa + identita' + validity dates
poi firma tutto con la propria PRIVATE KEY DigiCert
D->>L: 5. Restituisce certificato firmato (.p7s)
L->>B: 6. Invia email firmata + certificato .p7s
Note over B: 7. Prende PUBLIC KEY di DigiCert dal trust store
Note over B: 8. Verifica firma DigiCert sul certificato
→ firma valida = DigiCert ha firmato questo
Note over B: 9. DigiCert firma solo dopo aver verificato l'identita'
→ questa public key fu sottomessa da chi controlla lisa@azienda.com
→ la public key e' di Lisa ✓
Struttura completa del .p7s:
certificato-lisa.p7s
│
├── Public Key di Lisa
│ └── numero matematico (es. chiave RSA 2048 bit)
│
├── Identita'
│ ├── CN: Lisa Simpson
│ ├── E: lisa@azienda.com
│ └── O: Azienda Srl
│
├── Validity
│ ├── Not Before: 2024-01-01
│ └── Not After: 2025-01-01
│
├── Issuer
│ └── DigiCert Inc
│
└── Firma di DigiCert
└── SHA256(tutti i campi sopra) cifrato con PRIVATE KEY DigiCert
│
└── Bart verifica con PUBLIC KEY DigiCert (dal trust store)
→ firma valida = DigiCert ha costruito e firmato questo certificato
→ DigiCert lo ha fatto solo dopo aver verificato l'identita'
→ quindi: public key sopra = LisaIl punto chiave:
DigiCert non sa se la chiave "matematicamente appartiene" a Lisa — non esiste un modo matematico per provarlo. Quello che DigiCert fa e' piu' semplice: controlla che Lisa controlli l'email/dominio, poi mette la sua firma su "public key X + identita' Lisa". Tu ti fidi di DigiCert (e' nel trust store), quindi ti fidi della sua attestazione.
E' come un notaio: non sa se sei onesto, ma ha controllato il tuo documento d'identita' e ha messo il timbro. Chi si fida del notaio si fida del documento.


Una firma digitale e' un hash cifrato con la private key del mittente. Il destinatario la verifica con la public key del mittente (Gibson usa "decifra" — il termine corretto e' "verifica"). Se ha successo: authentication + non-repudiation + integrity. Se vedi "private key cifra" → firma digitale.
Encrypting Email#
Ci sono momenti in cui vuoi garantire che i messaggi email siano leggibili solo dagli utenti autorizzati. Puoi cifrare l'email e, come in qualsiasi altro caso in cui si usa la cifratura, la cifratura fornisce confidenzialita'.
Metodo 1 — Solo cifratura asimmetrica (semplificato):
Lisa vuole mandare un messaggio cifrato a Bart:
| Step | Chi | Cosa |
|---|---|---|
| 1 | Lisa | Recupera il certificato di Bart (contiene la sua public key) |
| 2 | Lisa | Cifra l'email con la PUBLIC KEY di Bart |
| 3 | Lisa | Manda l'email cifrata a Bart |
| 4 | Bart | Decifra l'email con la propria PRIVATE KEY |
Questo funziona perche' Bart e' l'unica persona che ha accesso alla propria private key. Se un attaccante intercettasse l'email, non potrebbe decifrarla senza la private key di Bart.
Quando cifri email: la PUBLIC KEY del destinatario cifra, la PRIVATE KEY del destinatario decifra. Le chiavi del mittente non sono coinvolte nella cifratura. Al contrario, la firma digitale usa solo le chiavi del mittente, non quelle del destinatario.
Metodo 2 — Cifratura ibrida: asimmetrica + simmetrica (come funziona davvero):
La descrizione precedente e' una spiegazione semplificata. La maggior parte delle applicazioni email combina cifratura asimmetrica e simmetrica. La cifratura asimmetrica e' lenta e inefficiente, quella simmetrica e' molto veloce.
Le applicazioni reali usano la cifratura asimmetrica per condividere privatamente una session key simmetrica, poi usano la cifratura simmetrica per cifrare i dati con quella session key.
sequenceDiagram
participant L as Lisa
participant B as Bart
Note over L: 1. Genera session key simmetrica (es. AES-256)
Note over L: 2. Cifra il corpo dell'email
con la session key → ciphertext
Note over L: 3. Recupera certificato di Bart
→ estrae la PUBLIC KEY di Bart
Note over L: 4. Cifra la session key
con PUBLIC KEY Bart → session key cifrata
L->>B: 5. Manda: [email cifrata] + [session key cifrata]
Note over B: 6. Decifra la session key
con propria PRIVATE KEY → session key in chiaro
Note over B: 7. Decifra l'email
con la session key → messaggio in chiaro

Gli utenti non autorizzati che intercettano l'email non riescono a leggerla perche' e' cifrata con la session key. Non riescono nemmeno a leggere la session key perche' e' cifrata con la public key di Bart — e solo la private key di Bart puo' decifrarla.
| Livello | Cosa viene cifrato | Con cosa | Perche' |
|---|---|---|---|
| Dati | Corpo dell'email | Session key AES | Velocita' — AES e' ottimizzato per grandi dati |
| Chiave | Session key | PUBLIC KEY Bart | Sicurezza — solo Bart puo' decifrarla |
Dev parallel: e' lo stesso pattern che usi in Node.js/PHP quando cifri dati con
crypto. Non cifri mai i dati direttamente con RSA (limite di dimensione, lentezza) — generi una chiave AES, cifri i dati con AES, cifri la chiave AES con RSA. Stessa architettura.
Precisione fondamentale sulla firma: non si firma l'email, si firma il suo digest (hash). La firma digitale non tocca mai il messaggio originale. Il digest e' piccolo (256 bit per SHA-256) indipendentemente dalla dimensione dell'email — firmare il digest e' veloce, firmare l'intera email con RSA sarebbe lentissimo e inutile.
Scenari email — tutti i casi:
| Scenario | Firma | Cifratura | Garantisce | Certificati necessari |
|---|---|---|---|---|
| 1. In chiaro, no firma | No | No | Niente | Nessuno |
| 2. In chiaro + firma digest | Si' (propria private key) | No | Authentication + Integrity + Non-repudiation | Certificato mittente |
| 3. Cifrata, no firma | No | Public key destinatario | Confidentiality | Certificato destinatario |
| 4. Cifrata + firma digest | Si' (propria private key) | Public key destinatario | Tutto e quattro | Entrambi i certificati |
Scenario 2 — In chiaro + firma del digest:
Alice:
1. hash(messaggio) → digest
2. cifra digest con propria PRIVATE KEY → firma digitale
3. Manda: messaggio in chiaro + firma + .p7s Alice
Bob:
4. Verifica firma con PUBLIC KEY Alice (dal .p7s) → digest originale
5. hash(messaggio ricevuto) → digest ricevuto
6. Confronta i due digest → match
Risultato: Bob sa che e' Alice (auth), che non e' stato modificato (integrity),
Alice non puo' negare (non-repudiation).
Chiunque intercetti legge il messaggio — nessuna confidentiality.Scenario 4 — Cifrata + firma del digest (caso completo):
Alice:
1. hash(messaggio) → digest
2. cifra digest con propria PRIVATE KEY → firma digitale
3. cifra messaggio con PUBLIC KEY Bob → ciphertext
4. Manda: ciphertext + firma + .p7s Alice
Bob:
5. decifra ciphertext con propria PRIVATE KEY → messaggio in chiaro
6. Verifica firma con PUBLIC KEY Alice (dal .p7s) → digest originale
7. hash(messaggio) → confronta digest → match
Risultato: Confidentiality + Authentication + Integrity + Non-repudiation"Anche qui CA?" — nel scenario 4 servono due certificati:
- Certificato di Alice (allegato da Alice come .p7s) → Bob lo usa per verificare la firma del digest
- Certificato di Bob (deve averlo Alice prima di mandare) → Alice lo usa per cifrare il messaggio
Come fa Alice ad avere il certificato di Bob?
- Bob le aveva gia' mandato una email firmata in precedenza (con il suo .p7s)
- Directory aziendale (LDAP/Exchange pubblica i certificati)
- Keyserver pubblico
Scenario extra — Email di gruppo:
Se mandi a 5 destinatari una email cifrata devi cifrare 5 volte — una copia del messaggio cifrata con la public key di ognuno. Non esiste una "chiave di gruppo". E' uno dei motivi per cui le mailing list cifrate sono complesse da gestire.
Firma = si firma il digest (hash), non il messaggio. Scenario 4 richiede due certificati: mittente (per verificare la firma) + destinatario (per cifrare). Se una domanda chiede "quale chiave cifra il messaggio email" → public key del destinatario. Se chiede "quale chiave firma" → private key del mittente sul digest.
S/MIME#
Secure/Multipurpose Internet Mail Extensions (S/MIME) e' uno degli standard piu' popolari per firmare digitalmente e cifrare le email. La maggior parte delle applicazioni email che supportano cifratura e firme digitali usano gli standard S/MIME.
S/MIME usa sia cifratura asimmetrica che simmetrica (il metodo ibrido del Metodo 2 sopra). Puo' cifrare email a riposo (memorizzate su disco) e in transito (inviate sulla rete). La versione corrente usa il Cryptographic Message Syntax (CMS), che permette di usare una grande varieta' di algoritmi di hashing e cifratura.
Molti algoritmi asimmetrici usano certificati e richiedono una PKI per distribuirli e gestirli. Quando si implementa S/MIME si usano tipicamente le porte:
| Porta | Protocollo | Espansione |
|---|---|---|
| 995 | POP3 over TLS | Post Office Protocol 3 over Transport Layer Security |
| 587 | SMTP over TLS | Simple Mail Transfer Protocol over Transport Layer Security |
| 993 | IMAP over TLS | Internet Message Access Protocol over Transport Layer Security |
S/MIME = firma + cifratura email. Usa cifratura ibrida (asimmetrica per la chiave, simmetrica per i dati). Porte: 995 POP3/TLS, 587 SMTP/TLS, 993 IMAP/TLS. Richiede PKI e certificati.
Certificati per chiunque — non solo aziende
La stessa PKI funziona per server, aziende e persone fisiche. Cambia solo cosa la CA verifica:
| Tipo certificato | Intestato a | Bruno (CA) verifica | Esempio CA |
|---|---|---|---|
| Server TLS | dominio (google.com) | che controlli il dominio (file HTTP o record DNS) | Let's Encrypt |
| Email / S/MIME | indirizzo email (franco@gmail.com) | che tu controlli quella casella (email di sfida) | Actalis, Sectigo |
| Code signing | organizzazione o persona | documento d'identita' + sede legale | DigiCert EV |
| Client certificate | persona fisica o dipendente | dipende dal livello (email, documento, presence) | CA aziendali |
Let's Encrypt fa solo certificati TLS per server — non fa S/MIME. Per email personali il provider gratuito piu' usato e' Actalis.
Franco e Sergio sono due amici — come fanno?
Nessuna azienda, nessun dominio. Tre strade:
Opzione A — Certificato personale gratuito (Actalis):
Franco va su actalis.com → inserisce franco@gmail.com
Actalis manda email di sfida → Franco clicca → identita' verificata
Certificato emesso: "questa public key = franco@gmail.com"
Funziona su Thunderbird, Outlook, Apple MailOpzione B — PGP/GPG (senza CA): Si scambiano le chiavi direttamente. E' il web of trust: nessuna CA, si fidano l'uno dell'altro dopo essersi incontrati. Franco firma la chiave di Sergio, Sergio firma quella di Franco.
Entrambi installano GPG
Si scambiano le public key via email / USB / keyserver
Thunderbird + Enigmail gestisce tuttoOpzione C — ProtonMail: Crea un account ProtonMail — le chiavi vengono generate e gestite in modo trasparente. Due amici con ProtonMail si scrivono cifrato senza toccare nulla.
| A — Actalis | B — GPG | C — ProtonMail | |
|---|---|---|---|
| CA necessaria | Si' (Actalis) | No | Si' (interna ProtonMail) |
| Difficolta' | Bassa | Alta | Zero |
| Funziona con Gmail/Outlook | Si' | Si' (plugin) | No (solo tra ProtonMail) |
| Modello fiducia | PKI classica | Web of trust | PKI gestita |
Cosa c'e' dentro un certificato X.509:
certificato.pem
│
├── Subject (intestatario)
│ ├── CN: sergio@gmail.com ← o "google.com" se e' un server
│ ├── O: (organizzazione — vuoto se persona fisica)
│ └── C: IT
│
├── Public Key ← la chiave pubblica di Sergio
├── Serial Number ← numero univoco assegnato dalla CA
├── Validity
│ ├── Not Before: 2025-01-01
│ └── Not After: 2026-01-01
├── Issuer: Actalis CA ← chi ha firmato
├── Key Usage ← cosa puo' fare (firma, cifratura, entrambi)
├── Subject Alternative Names ← altri domini/email coperti
│
└── CA Signature ← SHA256(tutti i campi sopra)
cifrato con la PRIVATE KEY della CACosa firma Bruno esattamente:
Bruno calcola:
SHA256(Subject + PublicKey + Serial + Validity + Issuer + KeyUsage + SAN)
→ un hash che rappresenta l'intero certificato
Bruno cifra quell'hash con la sua PRIVATE KEY → firma digitale
La firma viene allegata in fondo al certificato
Franco verifica:
Ricalcola SHA256 dei campi → confronta con la firma usando PUBLIC KEY Bruno
→ coincide = nessun campo e' stato toccato, Bruno ha firmato questo"Cosa contiene un certificato digitale?" → public key + identita' + validity + issuer + firma CA. Non contiene la private key — mai. "Cosa firma la CA?" → l'hash di tutti i campi del certificato (non solo la public key).
Il certificato e' firmato, non cifrato
Il certificato e' un documento pubblico — arriva sempre in chiaro, deve arrivarci. Senza leggerlo non puoi fare niente: non sai a chi appartiene la chiave, non sai quale CA ha firmato, non puoi ricalcolare l'hash.
| Firma digitale (certificato) | Cifratura | |
|---|---|---|
| Scopo | Integrita' + autenticita' | Confidenzialita' |
| Il documento e' | In chiaro + firma allegata | Cifrato, illeggibile |
| Chiunque puo' | Verificare la firma | No — solo il destinatario |
Il processo di verifica locale e' sempre lo stesso:
Certificato ricevuto (in chiaro):
Subject: sergio@gmail.com
Public Key: 3F9A... ← ti serve per usarla nella sessione
Issuer: DigiCert ← ti dice quale public key cercare nel trust store
Validity: 2025-2027
Signature: A7F3... ← la firma di DigiCert
Tu localmente:
1. Leggi "Issuer: DigiCert"
2. Apri trust store → prendi PUBLIC KEY di DigiCert
3. Ricalcoli SHA256(Subject + PublicKey + Validity + Serial + ...)
4. Usi PUBLIC KEY DigiCert per verificare la Signature → ottieni hash originale
5. Confronti i due hash → coincidono = valido, nessuno ha toccato nienteSolo la private key di DigiCert poteva produrre quella firma — nessun altro puo' falsificarla.
Dove trovi il certificato in chiaro nei diversi scenari:
| Scenario | Dove si trova |
|---|---|
| HTTPS | Il server lo manda durante il TLS handshake. Browser: lucchetto → Certificato |
| Email S/MIME | Allegato .p7s nell'email — visibile nelle intestazioni MIME |
| Code signing | Embedded nell'eseguibile (Windows PE / macOS app bundle) |
| Trust store locale | /etc/ssl/certs/ su Linux, Keychain su macOS, certmgr.msc su Windows |
# ricevi e leggi il certificato di un server in chiaro
openssl s_client -connect google.com:443 -showcerts
# decodifica un file .pem e mostra tutti i campi
openssl x509 -in certificato.pem -text -nooutOutput — esattamente i campi che la CA ha messo e firmato:
Subject: CN=sergio@gmail.com, C=IT
Issuer: CN=Actalis CA, O=Actalis S.p.A., C=IT
Validity:
Not Before: Jan 1 00:00:00 2025 GMT
Not After: Jan 1 00:00:00 2026 GMT
Public Key: (2048 bit RSA) 3F9A...
Signature Algorithm: sha256WithRSAEncryption
A7:F3:9B:...HTTPS Transport Encryption#
I metodi di transport encryption cifrano i dati in transito per garantire che rimangano confidenziali. Questo include dati trasmessi su Internet e su reti interne. SSH cifra traffico come SFTP. Questa sezione si concentra sui metodi di transport encryption usati con HTTPS.
TLS Versus SSL#
Transport Layer Security (TLS) e Secure Sockets Layer (SSL) sono protocolli di cifratura comunemente usati per cifrare dati inviati su Internet. SSL ha vulnerabilita' significative e non dovrebbe essere piu' usato. Tuttavia, molte persone si riferiscono ancora a TLS come "SSL/TLS" come se fossero la stessa cosa — quasi tutti i riferimenti a SSL sono da intendere come TLS.
E' comune cifrare HTTPS con TLS per garantire la confidenzialita' dei dati trasmessi su Internet. Puo' anche essere usato per cifrare altre trasmissioni come FTPS (File Transfer Protocol Secure).
TLS fornisce autenticazione basata su certificati e cifra i dati con una combinazione di cifratura simmetrica e asimmetrica durante una sessione:
- Asimmetrica per il key exchange (condividere privatamente una session key)
- Simmetrica per cifrare i dati trasmessi durante la sessione
TLS richiede certificati. Le CA emettono e gestiscono i certificati — una CA e' necessaria per supportare TLS. Le CA possono essere interne o esterne (terze parti).
TLS e' la sostituzione di SSL. TLS richiede certificati emessi da CA. TLS cifra il traffico HTTPS, ma puo' cifrare anche altro traffico.
| SSL | TLS | |
|---|---|---|
| Stato | Deprecato, vulnerabile | Standard attuale |
| Versioni sicure | Nessuna | TLS 1.2, TLS 1.3 |
| Usare oggi? | Mai | Si' — preferibilmente 1.3 |
| Riferimenti comuni | "SSL/TLS", "SSL certificate" | Quasi sempre intendono TLS |
Encrypting HTTPS Traffic with TLS#
HTTP Secure (HTTPS) e' comunemente usato su Internet per proteggere il traffico web. Usa TLS con cifratura sia asimmetrica che simmetrica.
HTTPS, TLS e AES — tre cose diverse, un solo risultato:
| HTTPS | TLS | AES | |
|---|---|---|---|
| Cos'e' | Protocollo web sicuro | Protocollo di sicurezza e trasporto | Algoritmo di cifratura simmetrica |
| Fa | Gestisce richieste/risposte web cifrate | Handshake, certificati, key exchange, cifratura del canale | Cifra blocchi di dati con una chiave |
| Livello | Applicazione | Trasporto | Matematica — un algoritmo |
| Porta | 443 (vs HTTP porta 80) | — | — |
| Senza l'altro | Non esiste senza TLS | Puo' cifrare anche FTP, SMTP, VPN | Puo' esistere da solo (es. cifrare un file su disco) |
| Analogia | La lettera + busta sigillata | Il servizio postale sicuro che gestisce tutto | Il lucchetto fisico sulla busta |
HTTP → aggiunge TLS → HTTPS
│
└── TLS usa internamente:
├── RSA / ECDH (asimmetrica — key exchange)
└── AES-256 (simmetrica — cifra i dati)HTTP diventa HTTPS perche' TLS crea un tunnel cifrato dentro cui HTTP viaggia normalmente. Il server web non cambia — risponde sempre con HTML/JSON come prima. Solo il canale e' diverso. AES non sa niente di HTTP o TLS: riceve dati + chiave, restituisce ciphertext. E' solo matematica — TLS decide quando chiamarlo e con quale chiave.
La cifratura asimmetrica non e' efficiente per grandi quantita' di dati — la simmetrica e' usata per cifrare i dati della sessione. Ma come fanno client e server a concordare la session key senza che qualcuno la intercetti? Non possono "sussurrarla" su Internet — sarebbe come un attore in TV che usa un sussurro teatrale: milioni di spettatori lo sentirebbero ugualmente.
Invece HTTPS usa la cifratura asimmetrica per trasmettere la session key in modo sicuro, poi usa quella session key con la cifratura simmetrica per cifrare tutti i dati della sessione.
TLS 1.2 — RSA key exchange:
sequenceDiagram
participant C as Client
participant S as Server
Note over C,S: TLS 1.2 — RSA key exchange
C->>S: 1. Richiesta HTTPS
S->>C: 2. Certificato + PUBLIC KEY server
Note over C: 3. Genera session key "53"
Cifra con PUBLIC KEY → "UcaNP@$$"
C->>S: 4. Manda "UcaNP@$$" [session key cifrata]
Note over S: 5. Decifra con PRIVATE KEY → "53"
Note over C,S: 6. AES con session key "53" per tutti i dati
- Il client apre una connessione HTTPS verso il server.
- Il server risponde inviando il proprio certificato digitale, che contiene la sua public key RSA.
- Il client genera una session key simmetrica casuale (AES-256) e la cifra con la public key del server. Solo il server puo' decifrarla.
- Il client trasmette la session key cifrata al server.
- Il server decifra la session key usando la propria private key RSA. Ora entrambi conoscono la session key.
- Da questo momento tutti i dati (HTML, JSON, form, immagini) vengono cifrati con AES usando quella session key.
Il problema di TLS 1.2: se qualcuno ha registrato il traffico oggi e in futuro ruba la private key del server, puo' decifrare tutto retroattivamente — perche' la session key era cifrata con quella private key. Nessuna Perfect Forward Secrecy.
TLS 1.3 — ECDHE key exchange:
sequenceDiagram
participant C as Client
participant S as Server
Note over C,S: TLS 1.3 — ECDHE key exchange
C->>S: 1. Client Hello + chiave pubblica ECDHE effimera del client
S->>C: 2. Server Hello + chiave pubblica ECDHE effimera del server
+ Certificato (firmato dalla CA)
Note over C: 3. Verifica firma CA sul certificato → autentico
Note over C: 4. Deriva session key:
propria chiave privata ECDHE × pubblica ECDHE server
Note over S: 4. Deriva session key:
propria chiave privata ECDHE × pubblica ECDHE client
Note over C,S: Session key MAI trasmessa — derivata indipendentemente da entrambi
AES con session key per tutti i dati
- Il client invia il Client Hello con la propria chiave pubblica ECDHE effimera — generata solo per questa sessione, scartata dopo.
- Il server risponde con la propria chiave pubblica ECDHE effimera + il certificato firmato dalla CA.
- Il client verifica la firma della CA sul certificato → conferma che la chiave ECDHE e' davvero del server, non di un impostore.
- Il client deriva la session key combinando la propria chiave privata ECDHE con la chiave pubblica ECDHE del server. Il server fa lo stesso nell'altro verso. Entrambi ottengono la stessa session key senza mai trasmetterla — e' matematicamente impossibile ricavarla intercettando solo le chiavi pubbliche ECDHE scambiate.
- Tutti i dati della sessione vengono cifrati con AES. Al termine, le chiavi ECDHE vengono scartate — non esistono piu'.
Il vantaggio di TLS 1.3: anche se domani qualcuno ruba la private key del server, il traffico di oggi e' al sicuro. Le chiavi ECDHE effimere sono gia' distrutte — non c'e' nulla da decifrare retroattivamente. Questo e' il Perfect Forward Secrecy.
| TLS 1.2 RSA | TLS 1.3 ECDHE | |
|---|---|---|
| Session key | Client la crea e la trasmette cifrata | Mai trasmessa — derivata da entrambi |
| Ruolo public key certificato | Cifra la session key | Autentica il server (firma le chiavi ECDHE) |
| Perfect Forward Secrecy | No — private key rubata = traffico passato decifrato | Si' — chiavi ECDHE effimere scartate dopo ogni sessione |
| Round trip | 2 | 1 (piu' veloce) |
| Usare oggi | Accettabile ma legacy | Standard raccomandato |
Dev parallel: quando in PHP/Symfony fai una chiamata
curla un'API HTTPS, sotto il cofano sta succedendo esattamente questo handshake — il tuo server fa da client. Se hai mai visto errori comeSSL certificate problem: unable to get local issuer certificate, e' perche' il trust store del server non conteneva la CA che ha firmato il certificato remoto. Curl usa/etc/ssl/certs/come trust store di default.
Downgrade Attacks on Weak Implementations#
Un downgrade attack e' un tipo di attacco che forza un sistema ad abbassare il proprio livello di sicurezza. L'attaccante poi sfrutta il controllo di sicurezza piu' debole. E' piu' spesso associato ad attacchi crittografici dovuti a implementazioni deboli di cipher suite.
Esempio con TLS e SSL:
Immagina un server che ha sia SSL che TLS installati. Se un client non riesce a usare TLS, il server fa il downgrade a SSL per accomodarlo.
flowchart TD
A["Charlie si connette al server"]
B["Charlie configura il suo sistema
per NON supportare TLS"]
C["Server: 'il client non supporta TLS'
→ downgrade a SSL"]
D["Charlie lancia attacchi SSL
es. POODLE"]
E["On-path (MITM) attack"]
A --> B --> C --> D --> D --> E
style D fill:#e05555,color:#fff
style E fill:#e05555,color:#fff
POODLE — caso reale:
POODLE (Padding Oracle On Downgraded Legacy Encryption) e' un attacco del 2014 che sfrutta SSL 3.0. Il nome e' un acronimo volutamente ironico. Il meccanismo: dopo il downgrade a SSL 3.0, l'attaccante sfrutta una debolezza nel modo in cui SSL gestisce il padding dei blocchi cifrati — riuscendo a decifrare un byte alla volta il contenuto della sessione.
Fix immediato quando fu scoperto: disabilitare SSL 3.0 su tutti i server. Google lo disabilitosubito; Internet Explorer 11 aggiunse un toggle. Chi non aveva aggiornato rimase vulnerabile.
Come prevenire i downgrade attack:
| Azione | Perche' |
|---|---|
| Disabilitare SSL completamente | Elimina qualsiasi possibilita' di downgrade a SSL |
| Disabilitare cipher suite deboli | Un server con cipher suite forti E deboli e' vulnerabile — l'attaccante sceglie la debole |
| Usare solo TLS 1.2 e 1.3 | TLS 1.0 e 1.1 hanno anch'essi vulnerabilita' note |
| HSTS (HTTP Strict Transport Security) | Il browser rifiuta connessioni non-HTTPS — previene downgrade a HTTP |
Gli amministratori dovrebbero disabilitare cipher suite deboli e protocolli deboli sui server. Quando un server ha sia cipher suite forti che deboli, gli attaccanti possono lanciare downgrade attack aggirandole quelle forti e sfruttando quelle deboli.
"Quale attacco forza un sistema a usare una versione piu' vecchia di TLS o SSL?" → Downgrade attack. "POODLE colpisce quale protocollo?" → SSL 3.0. "Come prevenire downgrade attack?" → disabilitare SSL e cipher suite deboli sul server.
Blockchain#
Blockchain è un registro pubblico distribuito e decentralizzato (distributed, decentralized, public ledger). Le banche usano ledger per tracciare depositi e prelievi — blockchain fa la stessa cosa ma pubblicamente, senza un'autorità centrale.
Dev parallel: pensa a un database append-only con foreign key obbligatoria all'ultimo record: ogni blocco punta al blocco precedente. Nessun UPDATE o DELETE — solo INSERT. E ogni riga è firmata da migliaia di nodi indipendenti.
Struttura di un blocco:
| Campo | Contenuto |
|---|---|
| Dati transazione | data, ora, importo |
| Parti coinvolte | firma digitale (non nomi reali) |
| Hash unico | identifica il blocco in modo univoco |
| Hash blocco precedente | crea la catena (chain) |
Il campo "hash blocco precedente" è il meccanismo che rende la blockchain tamper-proof: cambiare un blocco invalida tutti i blocchi successivi, perché ogni hash dipende dal contenuto del blocco e dall'hash del precedente.
Come viene aggiunto un blocco (4 fasi):
- Una transazione avviene
- La rete di computer verifica la transazione
- La transazione viene registrata accuratamente in un blocco
- Al blocco viene assegnato un hash unico
Bitcoin e i miner:
Bitcoin è una criptovaluta che usa blockchain. I computer che verificano e registrano le transazioni si chiamano miner. Guadagnano in due modi:
- Transaction fees — commissioni per ogni transazione
- Block rewards — ricompensa per ogni blocco minato
| Periodo | Block reward |
|---|---|
| Inizio | 50 BTC/blocco |
| Ogni 210.000 blocchi (~4 anni) | dimezzato (halving) |
| Maggio 2020 | 6.25 BTC/blocco |
| Futuro | 0 (solo transaction fees) |
Il halving garantisce che il numero totale di bitcoin sia limitato — nessuna banca centrale può stamparne di nuovi.
flowchart TD
T[Transazione avviene] --> V[Rete verifica]
V --> R[Registrata in blocco]
R --> H[Hash unico assegnato]
H --> C[Blocco aggiunto alla catena]
C --> |include hash blocco precedente| CHAIN[(Blockchain)]
style T fill:#1a2a1a,color:#7ec87e
style CHAIN fill:#0d1117,color:#58a6ff,stroke:#58a6ff
"Qual è la caratteristica principale di blockchain?" → distributed, decentralized, public ledger. "Cosa rende tamper-evident la blockchain?" → ogni blocco contiene l'hash del blocco precedente — modificarne uno invalida tutta la catena. "Cosa sono i miner?" → computer che verificano transazioni e ricevono block rewards.
Identifying Limitations#
Quando si valutano algoritmi crittografici, ogni scelta comporta trade-off tra sicurezza e risorse. Conoscere i limiti aiuta a scegliere l'algoritmo giusto per ogni contesto.
| Limitazione | Descrizione | Impatto pratico |
|---|---|---|
| Resource vs Security | Cifrare costa CPU, RAM, storage | ~40% overhead tipico su dati cifrati |
| Speed and Time | Algoritmo veloce per cifratura dati, lento per hashing password | bcrypt/Argon2 lenti per design: difesa brute-force |
| Size / Overhead | Lightweight crypto per device embedded (IoT) | AES-128 vs algoritmi ridotti per microcontroller |
| Entropy | Randomicità → sicurezza. Bassa entropia = algoritmo crackabile | SHA-1 deprecato dopo scoperta debolezze ~2010 |
| Predictability | PRNG deterministico: stesso input = stesso output → prevedibile | TRNG usa fattori ambientali (rumore atmosferico) |
Resource Versus Security Constraints#
Le organizzazioni devono bilanciare risorse disponibili e requisiti di sicurezza. La cifratura consume risorse — quindi non si cifra tutto indiscriminatamente.
Esempio concreto dal libro: un paragrafo di 260 caratteri in cleartext diventa ~360 caratteri in ciphertext (+40%). Moltiplicato per tutti i dati aziendali:
- +40% spazio disco
- Maggiore consumo di RAM durante il processing
- Tempo e potenza CPU aggiuntiva per cifrare/decifrare
I security expert vedono il costo aggiuntivo come necessario. I manager vedono il costo e cercano il miglior equilibrio tra costo risorse e bisogni di sicurezza.
Dev parallel: è lo stesso trade-off di SQL vs NoSQL, o di logging: loggare tutto costa. Si logga quello che serve. Stesso principio — scegliere cosa cifrare in base al rischio dei dati.
Speed and Time#
La velocità di un algoritmo dipende da due fattori:
- Quanti round (iterazioni) esegue sui dati
- Quanto veloce esegue ogni round
Veloce vs lento — dipende dal contesto:
| Scenario | Velocità desiderata | Perché |
|---|---|---|
| Cifratura/decifratura dati | Veloce | Latenza percettibile dall'utente |
| Hashing password (bcrypt, Argon2) | Lento (by design) | 1 password → nessun impatto. 100.000 tentativi brute-force → bottleneck |
Lo slowdown intenzionale degli hash password è una difesa esplicita contro il brute-force. Un attaccante che prova 100.000 password al secondo con SHA-256 veloce impiegherebbe pochi secondi. Con bcrypt lento, lo stesso attacco potrebbe richiedere anni.
Size and Computational Overhead#
Size in crittografia ha due accezioni:
- Memoria necessaria all'algoritmo per girare (overhead computazionale)
- Dimensione output rispetto all'input
Su desktop e server il primo punto è irrilevante. Sui dispositivi embedded e IoT (sensori, smart card, wearable) la memoria è limitata: entrano in gioco metodi di lightweight cryptography — algoritmi progettati con footprint ridotto.
Dev parallel: come scrivere un microservizio che gira in un container da 64MB vs un monolith da 2GB. Stessa funzione, vincoli di runtime completamente diversi.
Entropy#
L'entropia in crittografia = grado di casualità dell'algoritmo. Alta entropia → alta sicurezza. Bassa entropia → algoritmo crackabile più facilmente.
Gli algoritmi crittografici sono pubblici — chiunque può analizzarli. I crittanalisti pubblicano le loro scoperte. Peer review da parte della community. Se trovano debolezze, l'algoritmo viene deprecato.
Esempio: SHA-1 — debolezze crittografiche scoperte, non approvato per la maggior parte degli usi dal ~2010.
"SHA-1 è ancora sicuro?" → No, deprecato ~2010. Stesso concetto per MD5. Il Security+ chiede spesso di identificare algoritmi obsoleti/deboli.
Predictability#
La predictability in crittografia riguarda i generatori di numeri casuali usati per creare chiavi di cifratura.
Due tipi di RNG:
| Tipo | Espansione | Meccanismo | Problema |
|---|---|---|---|
| PRNG | Pseudo-Random Number Generator | Algoritmo deterministico: stesso input → stesso output | Se l'attaccante conosce l'input, può predire la chiave |
| TRNG | True Random Number Generator | Usa fattori ambientali (rumore atmosferico, timing hardware) | Vera entropia → imprevedibile |
Un PRNG è deterministico per design — utile per testabilità, ma un rischio se l'input è prevedibile o noto all'attaccante. I TRNG aggiungono vera entropia dall'ambiente fisico, rendendo la generazione imprevedibile.
flowchart LR
PRNG["PRNG
(algoritmo deterministico)"] -->|"stesso input → stesso output"| K1[Chiave prevedibile]
TRNG["TRNG
(entropia ambientale)"] -->|"rumore atmosferico / timing CPU"| K2[Chiave imprevedibile]
style PRNG fill:#2a1a1a,color:#e05555,stroke:#e05555
style TRNG fill:#1a2a1a,color:#7ec87e,stroke:#7ec87e
style K1 fill:#2a1a1a,color:#e05555
style K2 fill:#1a2a1a,color:#7ec87e
"Cosa usa un TRNG per generare numeri casuali?" → fattori ambientali (atmospheric noise). "Perché un PRNG può essere un rischio?" → stesso input = stesso output, quindi prevedibile se l'input è noto.
TRNG, TPM e Secure Enclave — la connessione hardware:
TPM e Secure Enclave usano TRNG hardware come fonte di entropia — è questo che li rende superiori a qualsiasi generazione di chiavi software.
| Hardware | TRNG | Fonte di entropia |
|---|---|---|
| TPM | Integrato nel chip | Rumore termico ed elettrico del silicio |
| Intel SGX | RDRAND/RDSEED (istruzioni CPU) | Digital Random Number Generator (DRNG) hardware Intel |
| Apple Secure Enclave | TRNG dedicato nel chip | Rumore hardware interno |
| ARM TrustZone | TRNG hardware | Rumore fisico del silicio |
Il TPM non solo genera la chiave con entropia vera — la sigilla: la chiave non esce mai dal chip. Qualsiasi operazione crittografica avviene dentro il TPM stesso.
Dev parallel: è la differenza tra
Math.random()in JavaScript (PRNG, deterministico, mai usarlo per crypto) ecrypto.getRandomValues()(attinge all'entropy pool del OS). Su Linux,/dev/urandomè alimentato da interrupt hardware, timing I/O, movimenti mouse — segnali fisici imprevedibili. Il TPM porta questo concetto a livello di chip dedicato, isolato dal resto del sistema.
Weak Keys#
Anche l'algoritmo più robusto è vulnerabile se la chiave è debole. Una weak key è una chiave corta — con meno bit, lo spazio delle chiavi possibili è ridotto e un attaccante può provarle tutte (brute-force) in tempi ragionevoli.
| Algoritmo | Chiave debole | Chiave raccomandata | Riferimento |
|---|---|---|---|
| RSA | 1024 bit | 2048 bit minimo | NIST dal 2010 |
| DES | 56 bit (unica opzione) | Deprecato — usa AES | Rimosso dal 2005 |
| AES | non applicabile (128/192/256 bit, tutti sicuri) | 128 bit minimo | NIST |
Dev parallel: come usare una password di 4 caratteri perché "tanto è cifrata". La lunghezza della chiave è il fattore moltiplicativo della difficoltà del brute-force — raddoppiare i bit non raddoppia la difficoltà, la eleva al quadrato.
Longevity#
La longevity di un algoritmo dipende dai progressi attesi nella potenza di calcolo. Man mano che i computer diventano più veloci, le chiavi che oggi sono sicure potrebbero diventare cracckabili.
RSA gestisce bene la longevity: aumentando la dimensione della chiave, aumenta esponenzialmente la difficoltà del brute-force — e quindi la vita utile dell'algoritmo.
Non tutti gli algoritmi supportano chiavi più grandi:
| Algoritmo | Key size flessibile? | Note |
|---|---|---|
| RSA | SI — 1024/2048/4096 bit | Raddoppiare la chiave = longevity molto maggiore |
| DES | NO — solo 56 bit | Non scalabile, deprecato nel 2005 |
| AES | SI — 128/192/256 bit | Successore di DES, approvato 2001 |
Timeline DES → AES:
- 1976 — DES approvato come standard federale USA (56 bit)
- 2001 — AES scelto come successore
- 2005 — DES rimosso dall'approvazione governativa USA. Non usarlo.
Reuse#
Con la cifratura simmetrica, la stessa chiave non dovrebbe essere riutilizzata — specialmente con i stream cipher. Se una chiave viene usata due volte sullo stesso stream, l'algoritmo diventa vulnerabile.
Esempio classico: WEP (Wired Equivalent Privacy)
| Dettaglio | |
|---|---|
| Problema | Le chiavi venivano riutilizzate nello stesso stream |
| Conseguenza | Vulnerabile ad attacchi — app pubbliche permettevano di scoprire le password WEP in minuti |
| Deprecato | 2004 |
| Successore | WPA → WPA2 → WPA3 |
"Perché WEP è insicuro?" → key reuse nello stesso stream. Non rispondere "password corta" o "algoritmo vecchio" — la causa specifica è il riutilizzo delle chiavi.
Plaintext Attack#
Una plaintext attack sfrutta la conoscenza (parziale o totale) del testo in chiaro per risalire al metodo di cifratura e applicarlo ad altri ciphertext.
| Tipo | Cosa ha l'attaccante | Difficoltà |
|---|---|---|
| Known-plaintext attack | Ciphertext + plaintext corrispondente completo | Quasi sempre efficace con risorse sufficienti |
| Chosen-plaintext attack | Ciphertext + porzione di plaintext nota (es. footer fisso) | Quasi sempre efficace con risorse sufficienti |
| Ciphertext-only attack | Solo il ciphertext, nessuna informazione sul plaintext | Efficace solo su algoritmi deboli/deprecati |
Esempio chosen-plaintext dal libro: un'azienda aggiunge sempre le stesse due frasi in fondo a ogni email (disclaimer legale). Se l'intera email è cifrata, l'attaccante conosce il plaintext del footer e può usarlo come punto di attacco per ricavare il metodo di decifratura — poi applicarlo al resto del messaggio.
Caso reale — Enigma (WWII): Bletchley Park usò exactly questo approccio per rompere la macchina Enigma dei nazisti. I messaggi militari tedeschi finivano quasi sempre con HEIL HITLER — plaintext noto, posizione fissa, ciphertext intercettato. Gli Alleati usavano questi crib (porzioni di plaintext conosciuto) per alimentare la Bombe di Turing ed escludere milioni di configurazioni impossibili. Enigma aveva anche un difetto strutturale che amplificava l'attacco: non poteva mai cifrare una lettera con sé stessa (A non diventava mai A), riducendo ulteriormente lo spazio delle possibilità.
Difesa: non usare algoritmi legacy e deprecati. Gli attacchi ciphertext-only falliscono su algoritmi moderni e robusti.
"Qual è la differenza tra known-plaintext e chosen-plaintext?" → known = attaccante ha plaintext completo + ciphertext. Chosen = attaccante ha solo una porzione nota del plaintext (es. header/footer fisso). "Quale attacco funziona solo su algoritmi deboli?" → ciphertext-only.
Exploring PKI Components#
Una PKI (Public Key Infrastructure) è un gruppo di tecnologie usate per richiedere, creare, gestire, archiviare, distribuire e revocare certificati digitali. La cifratura asimmetrica dipende dall'uso di certificati digitali per diversi scopi — proteggere le email, proteggere il traffico Internet con TLS. Le sessioni HTTPS che proteggono le transazioni con carta di credito online dipendono da una PKI.
Il beneficio principale di una PKI è che permette a due persone o entità di comunicare in modo sicuro senza essersi mai conosciute prima — cioè attraverso un mezzo pubblico non sicuro come Internet. Puoi stabilire una sessione sicura con Amazon.com anche se non l'hai mai fatto prima: Amazon usa certificati emessi da una CA fidata, e quel certificato fornisce la capacità di stabilire una sessione sicura. L'elemento chiave di una PKI è la certificate authority.
Certificate Authority#
Una Certificate Authority (CA) emette, gestisce, valida e revoca certificati. Le CA possono essere grandi, come Comodo o DigiCert (CA pubbliche), oppure piccole, come un singolo servizio in esecuzione su un server all'interno di una rete privata.
Le CA pubbliche guadagnano vendendo certificati. Perché questo funzioni, la CA pubblica deve essere fidata. Se la CA è fidata, tutti i certificati emessi da quella CA sono fidati. Questa fiducia si stabilisce attraverso il concetto di root of trust: la CA è un'entità fidata che fornisce una base solida per sistemi e processi sicuri.
È simile a come viene fidata la carta d'identità. L'Anagrafe del Comune emette la carta d'identità dopo aver verificato l'identità del cittadino. Se vuoi aprire un conto in banca o firmare un contratto, presenti la carta d'identità. La banca si fida del Comune/Stato italiano, quindi si fida del documento. Se invece mostrassi una tessera emessa da un'associazione privata sconosciuta, non verrebbe accettata.
Ma perché un computer dovrebbe fidarsi di una CA? La risposta si basa sul certificate trust path.
Certificate Trust Models#
Le CA vengono fidate inserendo una copia del loro root certificate nel trusted root certificate store del sistema operativo. I browser web più diffusi hanno anch'essi i loro trusted root certificate store. Il root certificate è il primo certificato creato dalla CA che la identifica, e lo store è semplicemente una raccolta di questi certificati root. Se il root certificate di una CA è inserito in questo store, tutti i certificati emessi da quella CA sono automaticamente fidati.

Le CA pubbliche come DigiCert e Comodo negoziano con gli sviluppatori di browser per far includere i loro certificati direttamente con il browser. In questo modo, tutti i certificati che vendono alle aziende sono automaticamente fidati.
Hierarchical trust model — il modello di fiducia più comune. In questo modello la CA pubblica, privata o governativa crea la prima CA, nota come root CA, che funge da trust anchor. Vengono create anche una o più intermediate CA, poiché la root CA viene tenuta offline per la propria sicurezza.
flowchart TD
ROOT["Root CA
(self-signed, trust anchor, OFFLINE)"] -->|"firma public key"| ICA1["Intermediate CA 1"]
ROOT -->|"firma public key"| ICA2["Intermediate CA 2"]
ICA1 -->|"leaf certificate"| E1["End-entity
code signing / HTTPS / S/MIME / VPN"]
ICA2 -->|"leaf certificate"| E2["End-entity
code signing / HTTPS / S/MIME / VPN"]
style ROOT fill:#1a2a3a,color:#58a6ff,stroke:#58a6ff
style ICA1 fill:#1a2a1a,color:#7ec87e,stroke:#7ec87e
style ICA2 fill:#1a2a1a,color:#7ec87e,stroke:#7ec87e
Come funziona il modello gerarchico:
- La root CA self-signed emette certificati a una o più intermediate CA e firma la public key di ciascuna intermediate CA (non la propria — vedi Cosa firma Bruno esattamente)
- Le intermediate CA emettono leaf certificate alle end-entity
- I leaf certificate emessi alle end-entity (organizzazioni, governi, utenti finali) possono essere per: code signing, digital signature, VPN, HTTPS per sessioni web cifrate, S/MIME per email cifrate, verifica identità e autenticazione
Certificate chaining combina tutti i certificati dalla root CA fino al certificato emesso alle end-entity. Per esempio, la figura 10.10 mostra la certificate chain di un wildcard certificate emesso a google.com — la catena include tutti e tre i certificati (root → intermediate → google.com).

In una piccola organizzazione, la root CA può emettere certificati direttamente ai dispositivi e agli utenti, senza intermediate CA. Tuttavia, tenere il root certificate online lo espone a possibili attacchi informatici.
| Livello | Ruolo | Online? |
|---|---|---|
| Root CA | Trust anchor — emette certificati alle intermediate CA, firma le loro public key | NO — tenuta offline |
| Intermediate CA | Emette leaf certificate alle end-entity | SI |
| Leaf certificate | Certificato finale per code signing, HTTPS, S/MIME, VPN, identità | — |
Dev parallel: come la catena di dipendenze npm. La fiducia si propaga dalla root verso il basso — se un pacchetto intermedio è compromesso, tutto ciò che dipende da lui è a rischio. Stessa logica: se la intermediate CA viene compromessa, tutti i certificati che ha emesso diventano inaffidabili. Per questo la root CA sta offline — è il nodo che, se compromesso, abbatte tutto.
"Perché la root CA è tenuta offline?" → se compromessa, tutti i certificati che ha emesso diventano inaffidabili — l'intera PKI collassa. "Cosa contiene il trusted root certificate store?" → i root certificate delle CA fidate. Se una CA è in quel store, tutti i suoi certificati sono automaticamente trusted. "Cos'è il certificate chaining?" → la catena completa root CA → intermediate CA → leaf certificate dell'end-entity.
"Certificate chaining" vs "certificate pinning" sono due cose diverse. Chaining = la catena root→intermediate→leaf. Pinning = il client accetta solo un certificato specifico hardcoded, anche se arrivasse un certificato valido e firmato da una CA trusted verrebbe rifiutato.
Caso reale — SSL/TLS Inspection aziendale:
Le aziende possono rimuovere le CA pubbliche dal trust store dei computer dei dipendenti e installare solo il proprio root certificate aziendale. Combinato con un proxy, permette di intercettare e ispezionare tutto il traffico HTTPS — pratica chiamata SSL/TLS inspection (o HTTPS inspection).
Dipendente → Proxy aziendale → Internet → Sito web
↑
intercetta il traffico TLS
decifra, ispeziona, ri-cifra
con certificato firmato dalla CA aziendaleIl browser del dipendente non genera nessun warning perché si fida della CA aziendale, che è nel trust store del computer.
| Vantaggio per l'azienda | Dettaglio |
|---|---|
| DLP (Data Loss Prevention) | Vede in chiaro cosa esce dalla rete — file riservati, upload su servizi esterni |
| Malware / C2 detection | Il traffico command & control dei malware viaggia spesso in HTTPS — senza inspection è invisibile |
| Compliance | Finanza, sanità, difesa: obbligo normativo di monitorare tutto il traffico |
| Servizi interni | Intranet e API interne firmate con la CA aziendale senza comprare certificati pubblici |
| Blocco siti | Possono leggere l'URL esatto anche su HTTPS e bloccare categorie specifiche |
Rischi e limiti:
- Il traffico personale del dipendente (banking, email, medico) è visibile all'azienda
- Se la chiave privata della CA aziendale viene compromessa, tutto il traffico storico è decrittabile
- Rompe le app con certificate pinning — quelle app rifiutano qualsiasi certificato che non sia quello hardcoded originale, incluso quello del proxy aziendale
Dev parallel: è come mettere nginx davanti a tutti i microservizi — nginx termina il TLS, ispeziona la request, ri-cifra e forwarda. Stesso principio, applicato a scala aziendale su tutto il traffico dei dipendenti verso Internet.
Registration Authority and CSRs#
Utenti e sistemi richiedono certificati digitali a una CA attraverso un processo di registrazione. In alcuni casi l'utente compila un form su un sito web. In altri casi invia un file con un formato specifico alla CA.
Esempio concreto — richiedere un certificato per un sito web:
flowchart TD
S1["Passo 1 - Creo coppia chiavi"] --> S2["Passo 2 - Genero CSR formato PKCS10"]
S2 --> S3["Passo 3 - Invio CSR alla CA senza priv key"]
S3 --> S4["Passo 4 - CA valida identita"]
S4 --> S5["Passo 5 - CA emette certificato con pub key"]
S5 --> S6["Passo 6 - Installo cert e priv key sul server"]
S6 --> S7["Passo 7 - Client avvia HTTPS sessione sicura"]
style S1 fill:#1a2a1a,color:#7ec87e,stroke:#7ec87e
style S3 fill:#2a1a1a,color:#e05555,stroke:#e05555
style S5 fill:#1a2a3a,color:#58a6ff,stroke:#58a6ff
OpenSSL è una libreria software accessibile via command line in molte distribuzioni Linux. Crea coppie di chiavi pub/priv in un comando e permette di esportare la pub key in un file in un secondo comando. Tecnicamente OpenSSL crea prima la chiave privata — dalla quale deriva la pub key. Le applicazioni sembrano crearle contemporaneamente ma l'ordine è sempre: prima priv, poi pub.
CSR (Certificate Signing Request):
- Contiene: scopo del certificato, info sul sito/entità, public key, informazioni sul richiedente
- Formato richiesto da quasi tutte le CA: PKCS #10 (Public-Key Cryptography Standards)
- La CA pubblica di solito un certificate template che mostra esattamente come formattare la CSR
- La private key NON è mai inclusa nella CSR — mai inviata alla CA
Il livello di validazione dell'identità varia molto:
- Certificati DV (Domain Validation) → basta dimostrare di controllare il dominio, a volte solo carta di credito
- Certificati OV (Organization Validation) → verifica dell'organizzazione
- Certificati EV (Extended Validation) → verifica estesa, processo lungo
Il primo passo è creare la chiave privata RSA — dalla quale viene derivata la chiave pubblica. La chiave pubblica viene inclusa nella CSR. La CA la incorpora nel certificato digitale. La chiave privata non viene mai inviata alla CA.
Registration Authority (RA):
In grandi organizzazioni una Registration Authority (RA) può assistere la CA raccogliendo le informazioni di registrazione dei certificati digitali. La RA non emette mai certificati — si occupa solo di assistere nel processo di registrazione.
| Entità | Cosa fa | Cosa NON fa |
|---|---|---|
| CA | Emette, gestisce, revoca certificati | — |
| RA | Raccoglie info di registrazione, assiste la CA | NON emette certificati |
"Qual è il primo passo per richiedere un certificato?" → creare la coppia di chiavi (prima la private key). "Cosa contiene una CSR?" → public key + info richiedente + scopo — mai la private key. "Cosa fa una RA?" → assiste la CA nella registrazione, NON emette certificati. "Che formato usa la CSR?" → PKCS #10.
Online Versus Offline CAs#
Se la CA è online — cioè accessibile in rete — è possibile inviare la CSR con un processo automatizzato. Le intermediate CA sono tipicamente online per questo motivo.
Un'organizzazione può invece tenere alcune CA offline per proteggerle da attacchi. Le CA offline accettano CSR solo manualmente — qualcuno deve fisicamente portare il supporto con la richiesta.
Perché tenere la root CA offline:
Le grandi organizzazioni tengono la root CA offline per ridurre il rischio di compromissione. La root CA emette certificati alle intermediate CA che sono online e accessibili.
| Scenario | Conseguenza |
|---|---|
| Intermediate CA compromessa | NON compromette l'intera certification path — la root CA può emettere nuovi certificati per sostituire quelli compromessi |
| Root CA compromessa | L'intera certification path è compromessa — tutti i certificati emessi da quella root CA diventano inaffidabili |
flowchart TD
ROOT["Root CA
OFFLINE
massima protezione"] -->|"emette cert alle"| ICA["Intermediate CA
ONLINE
accessibile via rete"]
ICA -->|"emette leaf cert"| END["End-entity
siti, utenti, app"]
COMP1["Intermediate CA compromessa"] -->|"root CA emette nuovi cert"| FIX["Certification path ripristinata
root CA intatta"]
COMP2["Root CA compromessa"] --> FAIL["Intera certification path
compromessa — nessun rimedio"]
style ROOT fill:#1a2a3a,color:#58a6ff,stroke:#58a6ff
style COMP2 fill:#2a1a1a,color:#e05555,stroke:#e05555
style FAIL fill:#2a1a1a,color:#e05555,stroke:#e05555
style FIX fill:#1a2a1a,color:#7ec87e,stroke:#7ec87e
"Perché la root CA è tenuta offline?" → per proteggerla da attacchi — se compromessa, l'intera certification path collassa senza rimedio. "Se una intermediate CA viene compromessa, cosa succede?" → la root CA (intatta) può emettere nuovi certificati per sostituire quelli compromessi — la certification path è ripristinabile.
Updating and Revoking Certificates#
Certificate Revocation List#
Validating a Certificate#
Certificate Pinning#
Key Escrow#
Key Management#
Comparing Certificate Types#
Comparing Certificate Formats#
Collegato a#
- crypto - cifratura, hash, certificati, TLS
- network - protocolli crittografici di rete
- cap-09-implementing-controls - capitolo precedente
Key stretching non cifra la password nel senso tradizionale: il risultato e' ancora un hash non reversibile. "Stretching" si riferisce all'allungamento del tempo computazionale necessario, non alla lunghezza dell'output. ↩︎
Salt e pepper hanno ruoli diversi: il salt e' unico per ogni utente ed e' memorizzato nel database accanto all'hash. Il pepper e' condiviso tra tutti gli utenti ed e' memorizzato fuori dal database. Perdere il database non espone il pepper. ↩︎
BIP39 (mnemonic wallet Bitcoin) usa esattamente PBKDF2-HMAC-SHA512 per derivare il seed dalle parole mnemoniche:
PBKDF2(password=mnemonic, salt="mnemonic"+passphrase, iterations=2048). La passphrase opzionale (la "25a parola") e' il salt aggiuntivo in questa operazione. ↩︎Data at rest / in transit / in use e' un framework che compare ovunque in Security+. Vedi anche cap-03-security-architecture per la sezione sui protocolli sicuri in transito. ↩︎
Il cifrario di Cesare (shift 3) e ROT13 sono cifrari monoalfabetici: ogni lettera e' sempre sostituita dalla stessa lettera. Vulnerabili all'analisi delle frequenze (in italiano la "e" e' la lettera piu' frequente — basta cercare la lettera piu' frequente nel ciphertext per trovare lo shift). La crittografia polialfabetica usa alfabeti multipli per resistere a questo attacco. La crittoanalisi e' la disciplina che studia come interpretare messaggi cifrati senza conoscere la chiave — e' il nome formale di tutti gli attacchi che Gibson descrive (brute force, dictionary, birthday attack). ↩︎
NIST (National Institute of Standards and Technology) — agenzia governativa USA che definisce standard tecnici e framework di sicurezza. Per la crittografia: ha selezionato AES nel 2001 dopo una competizione pubblica internazionale tra algoritmi, ha approvato SHA-2 e SHA-3, pubblica le linee guida FIPS (Federal Information Processing Standards) che diventano il riferimento mondiale. Ruolo chiave nell'esame: quando Gibson dice "NIST raccomanda" o "NIST ha adottato", significa che quell'algoritmo o pratica e' lo standard ufficiale USA. Vedi voce completa in glossario-cyber. ↩︎ ↩︎
Bruce Schneier — crittografo e security researcher americano, considerato una delle voci piu' autorevoli nel settore. Autore di "Applied Cryptography" e del blog Schneier on Security. Ha progettato Blowfish (1993) e Twofish (1998). Nei testi security il suo nome e' spesso citato come sinonimo di "fonte affidabile". ↩︎
CA — Certificate Authority — ente (pubblico o privato) che emette, firma e revoca certificati digitali. Verifica l'identita' del richiedente prima di emettere il certificato, poi lo firma con la propria private key. Esempi pubblici: DigiCert, Let's Encrypt, Comodo. Esempi interni: Windows Certificate Services, una CA aziendale privata. La CA root e' il vertice della chain of trust — la sua chiave privata e' tenuta offline per sicurezza massima. Se una CA viene compromessa (es. DigiNotar 2011), tutti i suoi certificati diventano inaffidabili e viene rimossa dal trust store. Vedi voce completa in glossario-cyber. ↩︎
PKI — Public Key Infrastructure — non e' un singolo algoritmo o prodotto, e' l'infrastruttura completa che gestisce il ciclo di vita delle chiavi pubbliche: creazione, distribuzione (certificati), verifica (chain of trust), revoca (CRL/OCSP) e rinnovo. La "I" di Infrastructure enfatizza che CA, certificati, trust store, CRL e policy di revoca sono tutti parte di un sistema unico. Senza PKI, l'asymmetric encryption sarebbe vulnerabile al MITM perche' non ci sarebbe modo di verificare a chi appartiene una public key. Vedi voce completa in glossario-cyber. ↩︎
Beacon — segnale (faro, indicatore). In inglese un beacon e' qualsiasi segnale usato per guidare, identificare o tracciare. Etimologia: dal germanico antico baukna = segnale. In security: segnale periodico emesso da un dispositivo per annunciare la propria presenza (Wi-Fi beacon frame, audio beacon, Bluetooth beacon). ↩︎




