Questa guida copre l'uso di OpenSSL per la Crittografia Simmetrica (SIMM), la Crittografia Asimmetrica (ASIMM - RSA), e la Firma Digitale. Esercitazione sistemi e reti - AS 2025-26
Si utilizza AES-256-CBC con PBKDF2 per una derivazione sicura della chiave (passphrase), essenziale per l'Internet Security.
echo "Scrivi un testo di prova anche su più righe. Solo la chiave corretta sarà in grado di decifrarlo." > msg_originale.txt
cat msg_originale.txt
Il flag -pbkdf2
usa un Key Derivation Function moderno per prevenire attacchi di forza bruta.
openssl enc -aes-256-cbc -salt -pbkdf2 -in msg_originale.txt -out msg_cifrato.txt
NB si usano gli stessi flag, aggiungendo -d
(decrypt).
openssl enc -aes-256-cbc -salt -pbkdf2 -d -in msg_cifrato.txt -out msg_decifrato.txt
# verifica e confronto
# metodo 1
# Se l'output di diff -u è vuoto, significa che i file sono identici bit-per-bit, confermando che la crittografia e decrittografia sono riuscite perfettamente.
diff -u msg_originale.txt msg_decifrato.txt
# metodo 2
# Se l'output di cmp è vuoto, significa che i file sono identici bit-per-bit
cmp msg_originale.txt msg_decifrato.txt
# metodo 3
# Generando due hash e confrontandoli
sha256sum msg_originale.txt && sha256sum msg_decifrato.txt
L'algoritmo RSA si basa sui Test di Primalità per generare chiavi sicure (minimo 2048 bit).
# 1. Genera la Chiave Privata (protetta da passphrase).
# NB la password deve avere almeno 4 caratteri
openssl genrsa -aes256 -out privata.key 2048
# 2. Estrae la Chiave Pubblica (pubblica.pem).
openssl rsa -in privata.key -pubout -out pubblica.pem
La Firma Digitale serve a garantire l'integrità e l'autenticità del documento.
# 1. FIRMA: Crea la firma con la chiave privata.
openssl dgst -sha256 -sign privata.key -out documento.sig messaggio.txt
# 2. VERIFICA: Verifica la firma con la chiave pubblica.
openssl dgst -sha256 -verify pubblica.pem -signature documento.sig messaggio.txt
OpenSSL non è solo uno strumento crittografico; è anche una suite che espone utility matematiche fondamentali, inclusi strumenti per manipolare numeri interi grandi e verificarne la primalità, che sono i mattoni dell'algoritmo RSA.
3.1 Generazione di Numeri Primi (Pseudo-Primalità)
Puoi usare il comando prime per generare o testare numeri. Per creare chiavi RSA sicure, i moduli primari devono essere estremamente grandi (2048 bit in RSA).
# Genera un numero primo grande di 128 bit (solo un esempio, non sicuro per RSA)
openssl prime -generate -bits 128
# Output Esempio: 340282366920938463463374607431768211501
3.2 Verifica della Primalità di un Numero
Il sottocomando prime può anche testare se un numero specifico (spesso generato casualmente) è primo.
openssl prime 1729
# Output: 1729 is not prime (1729 = 7 * 13 * 19)
# Testare un numero primo noto (esempio: 41)
openssl prime 41
# Output: 41 is prime
Di seguito riportiamo codice bash da eseguire da linea di comando, seguendo le istruzioni:
- crea uno script vuoto con nano o pico, ad esempio nano rsa.sh
- inserisci nel file il contenuto sotto riportato, riportando accuratamente il contenuto
- esci salvando con CTRL X
- assegna i permessi di esecuzione al file con
chmod +x rsa.sh
e premi Invio - digita
./nome_file.sh
e premi Invio per lanciare lo script - Analizza il contenuto e prova a verificare se corretto
- commenta lo script nelle sezioni indicate, provando a spiegare a cosa servono A) gcd B) modinv
- quanto possono essere grandi i numeri p e q al massimo, in modo da lanciare lo script senza errori?
#!/bin/bash
# --- gcd ---
gcd() {
a=$1
b=$2
while [ $b -ne 0 ]; do
t=$b
b=$((a % b))
a=$t
done
echo $a
}
# --- inverso modulare ---
modinv() {
a=$1
m=$2
m0=$m
x0=0
x1=1
while [ $a -gt 1 ]; do
q=$((a / m))
t=$m
m=$((a % m))
a=$t
t=$x0
x0=$((x1 - q * x0))
x1=$t
done
if [ $x1 -lt 0 ]; then
x1=$((x1 + m0))
fi
echo $x1
}
# --- piccoli primi casuali ---
p=$(openssl prime -generate -bits 6) # numeri piccolissimi per bash
q=$(openssl prime -generate -bits 6)
while [ "$p" -eq "$q" ]; do
q=$(openssl prime -generate -bits 6)
done
echo "Primi scelti: p=$p, q=$q"
n=$((p * q))
phi=$(((p - 1) * (q - 1)))
echo "n = $n"
echo "phi(n) = $phi"
# --- scelta e ---
e=3
while [ $(gcd $e $phi) -ne 1 ]; do
e=$((e + 2))
done
echo "e scelto = $e"
# --- calcolo d ---
d=$(modinv $e $phi)
echo "d calcolato = $d"
# --- chiavi ---
echo "Chiave pubblica: (e=$e, n=$n)"
echo "Chiave privata: (d=$d, n=$n)"
# --- cifratura e decifratura con Python per sicurezza ---
message=$((RANDOM % n))
cipher=$(python3 -c "print(pow($message,$e,$n))")
decipher=$(python3 -c "print(pow($cipher,$d,$n))")
echo "Messaggio originale: $message"
echo "Messaggio cifrato: $cipher"
echo "Messaggio decifrato: $decipher"
Test eseguiti su RSA
Primi scelti: p=53, q=59
n = 3127
phi(n) = 3016
e scelto = 3
d calcolato = 2011
Chiave pubblica: (e=3, n=3127)
Chiave privata: (d=2011, n=3127)
Messaggio originale: 565
Messaggio cifrato: 3019
Messaggio decifrato: 565
--
Primi scelti: p=59, q=53
n = 3127
phi(n) = 3016
e scelto = 3
d calcolato = 2011
Chiave pubblica: (e=3, n=3127)
Chiave privata: (d=2011, n=3127)
Messaggio originale: 352
Messaggio cifrato: 1939
Messaggio decifrato: 352