Parte V — Fare cose vere
Capitolo 19 — Cybersecurity difensiva
Leo porta in dotazione un'area ricca di strumenti di sicurezza. Il taglio è dichiaratamente difensivo: proteggere i propri dati, i propri account, i propri file. Non si tratta di attaccare sistemi altrui, ma di costruire programmi che custodiscono bene ciò che gli affidi e di capire, con mano, i concetti che reggono la sicurezza di tutti i giorni. In questo capitolo tocchiamo i quattro pilastri: password robuste, integrità, riservatezza e autenticazione.
🦁 Curiosità — Il verme che svegliò tutti
Nel novembre del 1988 un piccolo programma sperimentale sfuggì di mano e divenne il primo a diffondersi da solo su vasta scala attraverso Internet, rallentando migliaia di computer collegati alla rete. L'episodio mostrò al mondo quanto contasse la sicurezza e portò, pochi mesi dopo, alla nascita dei primi centri di risposta agli incidenti informatici. Da allora la difesa ha smesso di essere un pensiero secondario.
Password: misurarle e generarle
La prima linea di difesa di qualunque account è la password. Leo sa giudicarne la robustezza senza pietà e senza illusioni:
variabile f = misura_forza_password("ciao123")
scrivi "Livello: {f["livello"]}, punteggio {f["punteggio"]} su 4"
scrivi "È tra le più comuni? {f["comune"]}"Livello: pessima, punteggio 0 su 4
È tra le più comuni? veromisura_forza_password restituisce un dizionario con il livello, un punteggio da 0 a 4, i bit di casualità stimati, il tempo che ci vorrebbe a indovinarla e se è fra le password più usate al mondo. C'è anche spiega_forza_password, che dà un verdetto in italiano con i problemi puntati uno per uno — ottimo da mostrare a un utente che sta scegliendo una password.
E le password robuste Leo le sa anche creare, in forme pensate per essere davvero usabili: genera_frase_password(6) mette in fila parole italiane a caso (come zucca-latte-tetto-gradino-...), facili da ricordare e difficilissime da indovinare; genera_password_pronunciabile() ne crea una leggibile ad alta voce; genera_pin() evita gli schemi deboli come 1234 o gli anni. Una frase di sei parole generata così raggiunge una robustezza «ottima» — centinaia di bit di casualità — restando qualcosa che un essere umano può ricordare.
Integrità: accorgersi delle modifiche
Come fai a sapere che un file non è stato alterato? Calcolando la sua impronta crittografica: un codice che cambia completamente anche per la più piccola modifica, ma dal quale non si può risalire al contenuto. Lo abbiamo già visto con impronta; qui lo usiamo per il suo scopo tipico, verificare l'integrità:
variabile originale = impronta("contratto versione 1")
variabile modificato = impronta("contratto versione 1 ")
scrivi "Uguali? {originale == modificato}"Uguali? falsoAbbiamo aggiunto un solo spazio in fondo, e l'impronta è completamente diversa. Su questo principio si fonda la verifica dei download, il controllo che un file non sia stato manomesso, e — nell'area forense di Leo — funzioni come impronta_albero, che fotografa una cartella intera (impronta, dimensione e data di ogni file) e confronta_alberi, che dice esattamente cosa è cambiato tra due fotografie. È lo strumento con cui, per esempio, accorgersi che qualcosa in una cartella di sistema è stato toccato.
Riservatezza: cifrare per un destinatario
Per tenere un messaggio segreto agli occhi di tutti tranne il destinatario, si usa la crittografia a chiave pubblica. L'idea è elegante: ciascuno ha una coppia di chiavi, una pubblica (che può dare a tutti) e una privata (che tiene per sé). Chiunque può cifrare un messaggio con la tua chiave pubblica, ma solo tu, con la privata, puoi aprirlo.
variabile chiavi = crea_chiavi_riservatezza()
variabile busta = cifra_per("Il codice del caveau è 4821", chiavi["pubblica"])
variabile aperto = decifra_da(busta, chiavi["privata"])
scrivi "Messaggio aperto: {aperto}"Messaggio aperto: Il codice del caveau è 4821crea_chiavi_riservatezza genera la coppia; cifra_per(dati, pubblica) chiude il messaggio in una «busta» leggibile solo con la privata corrispondente; decifra_da(busta, privata) la riapre. Ci sono anche le versioni per i file (cifra_file_per, decifra_file_da) e per più destinatari insieme (busta_per_molti). Nota bene: nell'esempio generiamo le chiavi sul momento; nel mondo reale la chiave privata va custodita con cura — se la perdi, perdi l'accesso; se te la rubano, perdi il segreto.
💡 L'idea — La cassaforte e il sigillo
Cifrare un messaggio è come chiuderlo in una cassaforte di cui solo il destinatario ha la chiave: chiunque può vedere la cassaforte, ma nessun altro può aprirla. L'impronta crittografica, invece, è come il sigillo di ceralacca su una busta: non nasconde il contenuto, ma rivela subito se qualcuno l'ha aperta o modificata. Riservatezza e integrità rispondono a due domande diverse — «chi può leggere?» e «è stato toccato?» — ed è per questo che si usano strumenti diversi.
Autenticazione: i codici a tempo
I codici OTP — quelli che leggi sull'app di autenticazione e che cambiano ogni trenta secondi — sono il secondo fattore che protegge i tuoi account. Leo li sa calcolare. Qui chiediamo il codice valido a un istante preciso (così il risultato è riproducibile):
variabile segreto = "JBSWY3DPEHPK3PXP"
scrivi "Codice alle 1700000000: {codice_otp_a(segreto, 1700000000)}"Codice alle 1700000000: 324550A partire da un segreto condiviso, codice_otp_a(segreto, istante) calcola il codice valido in quel momento. Nell'uso reale si usa codice_otp(segreto) per il codice di adesso e verifica_codice_otp(segreto, codice) per controllarlo. Leo sa anche produrre il codice QR (qr_otp_svg, salva_qr_otp) con cui configurare l'app di autenticazione. Con questi pezzi puoi costruire, per capire come funziona, il tuo piccolo sistema a due fattori.
Forense di base: il file dice la verità?
Chiudiamo con uno strumento investigativo: capire il vero tipo di un file, indipendentemente dall'estensione. Un malware si traveste spesso cambiando l'estensione; Leo guarda il contenuto.
scrivi_file("finto.png", "Questo non è un PNG, è testo")
variabile esito = estensione_coerente("finto.png")
scrivi "Coerente? {esito["coerente"]}"
scrivi(esito["avviso"])Il programma crea un file chiamato finto.png che in realtà contiene testo, e estensione_coerente lo smaschera: restituisce coerente: falso e un avviso che spiega che il file, malgrado l'estensione .png, è in realtà testo. Su questo si costruiscono il triage dei file e le regole di scansione in stile YARA della scheda LIBRERIA_FORENSE.md.
Una nota di responsabilità
Questi strumenti sono potenti e servono a proteggere. Usali per quello: le tue password, i tuoi file, i sistemi che amministri o per cui hai un permesso esplicito. La crittografia e l'analisi sono conoscenze preziose proprio perché chi le capisce sa difendersi meglio. Impararle su te stesso — cifrando i tuoi appunti, verificando le tue cartelle — è il modo giusto per farle tue.
Prova tu
- Scrivi un «controllore di password» che chiede una password all'utente e stampa il verdetto di
spiega_forza_password, poi gli propone unagenera_frase_passwordcome alternativa robusta. - Cifra un piccolo file con
cifra_file_perusando una coppia di chiavi appena creata, poi riaprilo condecifra_file_dae verifica che il contenuto coincida. - Crea un file
relazione.pdfche in realtà contiene testo e usaestensione_coerenteper smascherarlo; stampa l'avviso che Leo restituisce.