Crittografia
Cifratura, codifica e hashing: che cosa fa ciascuno
Distingui codifica, cifratura e hashing con laboratori su Base64, SHA-256 e OpenSSL. Impara perché Base64 non protegge niente e perché gli hash sono unidirezionali.
Il cifrario di Cesare fa scorrere ogni lettera di un numero fisso di posizioni. Cifra HELLO in KHOOR a mano, inverti il processo e vedi perché fallisce.
Il cifrario di Cesare è un cifrario a sostituzione. Sostituisce ogni lettera con un'altra che si trova un numero fisso di posizioni più in là nell'alfabeto. Fai avanzare ogni lettera di tre posizioni e HELLO diventa KHOOR. Il nome viene da Giulio Cesare che, secondo la tradizione, usava uno scorrimento di questo tipo nei suoi messaggi. È abbastanza semplice da poterlo applicare a mano, e proprio per questa semplicità non dà quasi nessuna sicurezza.
Scrivi l'alfabeto su una riga. Su una seconda riga scrivi lo stesso alfabeto spostato di tre, ricominciando dall'inizio dopo la Z:
Plain: ABCDEFGHIJKLMNOPQRSTUVWXYZ
Shift: DEFGHIJKLMNOPQRSTUVWXYZABCPer cifrare, trova ogni lettera del testo in chiaro nella riga in alto e copia la lettera subito sotto. H diventa K, E diventa H, L diventa O e O diventa R. Così HELLO diventa KHOOR. La chiave è la quantità di scorrimento, qui 3.
Spazi, cifre e punteggiatura non fanno parte dell'alfabeto dalla A alla Z. Una versione didattica può lasciarli invariati, e il codice Python qui sotto fa così.
La decifratura è la stessa tabella letta al contrario. Fai arretrare ogni lettera di tre posizioni, che equivale a farla avanzare di 23:
KHOOR → HELLOPer una data chiave, ogni lettera del testo in chiaro corrisponde a una sola lettera del testo cifrato, e la corrispondenza inversa è altrettanto univoca. Per questo il cifrario si può invertire quando conosci la chiave.
L'alfabeto inglese ha 26 lettere, quindi gli scorrimenti si ripetono ogni 26 posizioni. Uno scorrimento di 29 fa la stessa cosa di uno di 3:
29 mod 26 = 3Uno scorrimento di −3 fa la stessa cosa di uno di 23. Quando scrivi il codice, prendi lo scorrimento modulo 26 così funziona con qualsiasi intero.
Questa funzione fa scorrere solo le lettere dalla A alla Z e dalla a alla z, lascia invariato tutto il resto e ricomincia dall'inizio con il modulo 26. Usa ord e chr per convertire tra lettere e numeri:
def caesar(text, shift):
out = []
for ch in text:
if ch.isascii() and ch.isalpha():
base = ord('A') if ch.isupper() else ord('a')
out.append(chr((ord(ch) - base + shift) % 26 + base))
else:
out.append(ch)
return ''.join(out)
print(caesar("HELLO", 3))
print(caesar("KHOOR", -3))
print(caesar("KHOOR", 23))
print(caesar("HELLO", 29))
print(caesar("ATTACK AT DAWN", 3))
print(caesar(caesar("Hello, World!", 13), 13))
print(caesar("Hello, World!", 13))
print(caesar("hello, world", 3))
print(caesar("KHOOR", 26 - 3) == caesar("KHOOR", -3))
print(sum(1 for s in range(1, 26) if caesar("KHOOR", s) == "HELLO"))
print(caesar("HELLO", 3) == caesar("HELLO", 29))L'output dello script:
KHOOR
HELLO
HELLO
KHOOR
DWWDFN DW GDZQ
Hello, World!
Uryyb, Jbeyq!
khoor, zruog
True
1
TrueL'output conferma le sezioni precedenti. Gli scorrimenti −3 e 23 coincidono, e così pure 3 e 29. Tra gli scorrimenti da 1 a 25, solo uno riporta KHOOR a HELLO. Applicare due volte lo scorrimento 13 restituisce il testo originale, che è il caso di ROT13 descritto più avanti.
Con un alfabeto di 26 lettere, solo 25 scorrimenti cambiano il testo. Un attaccante può provarli tutti e controllare quale risultato è leggibile. Con un testo inglese il risultato leggibile salta all'occhio, quindi l'attacco non costa quasi nulla.
Anche le frequenze delle lettere sopravvivono allo scorrimento. In inglese la E è comune e la Z è rara, quindi un testo cifrato in cui una lettera compare molto più spesso delle altre è un indizio forte. Anche senza provare ogni scorrimento, il conteggio delle lettere indica la chiave.
Il cifrario serve a imparare il vocabolario della crittografia: testo in chiaro, testo cifrato, chiave, sostituzione e brute force. Non deve proteggere password, dati dei clienti, chiavi API o file privati. La cifratura vera usa algoritmi standardizzati, chiavi generate correttamente e una gestione attenta delle chiavi. La voce del glossario NIST sulla crittografia dà le definizioni formali del campo.
ROT13 è un cifrario di Cesare con scorrimento 13. È l'inverso di se stesso: applicarlo due volte restituisce il testo originale, perché 13 + 13 = 26 e un giro completo dell'alfabeto non cambia nulla. L'output di ROT13 su Hello, World! è Uryyb, Jbeyq!, come mostrato sopra.
ROT13 si usa per nascondere spoiler o battute a un'occhiata distratta. Non dà nessuna vera protezione, perché chi conosce il metodo lo legge in pochi secondi.
Cifra ATTACK AT DAWN a mano con uno scorrimento di 3, conservando gli spazi. Confronta la tua risposta con questa:
DWWDFN DW GDZQPoi cambia lo scorrimento nella funzione Python ed eseguila sullo stesso testo. Prova lo scorrimento 0, lo scorrimento 26 e lo scorrimento 13, e prevedi ogni risultato prima di eseguire. Usa un testo di prova sintetico o tuo, e tieni l'esercizio sulla tua macchina.
Quando sei pronto, il prossimo articolo, Cifrario di Cesare in Python, parte da questa funzione e aggiunge la gestione dell'input e i test.
Per saperne di più: la voce del glossario NIST sulla crittografia e la documentazione Python per ord e chr.
Crittografia
Distingui codifica, cifratura e hashing con laboratori su Base64, SHA-256 e OpenSSL. Impara perché Base64 non protegge niente e perché gli hash sono unidirezionali.
Crittografia
Perché gli hash veloci non vanno bene per le password, a cosa servono salt e work factor e come calcolare e verificare un hash con Argon2id in Python usando argon2-cffi.
Crittografia
Chiavi pubbliche e private da zero: cosa dimostra una firma, perché la chiave privata resta segreta e un lab con Ed25519 in cui un file modificato non passa la verifica.