Proteggere i propri dati personali (parte 4): crittografia simmetrica con GPG

Breve PoC che mostra come crittografare rapidamente un file utilizzando il sistema a cifratura simmetrica fornito da GNU Privacy Guard o GPG. Questo metodo sfrutta la stessa chiave privata sia in fase di encryption che in fase di decryption, e risulta particolarmente comodo se si desidera cifrare solo alcuni dati e non si vuole impostare una coppia di chiavi (necessaria per la crittografia asimmetrica e le firme digitali).

GPG supporta diversi algoritmi di cifratura (ciphers), tra cui AES-256,  Blowfish e CAST-5. È possibile vedere la lista completa digitando da terminale:

gpg_scr10

Di default, l’algoritmo utilizzato come cifrario simmetrico è AES-128, allo stato attuale praticamente incrackabile poiché, anche con un supercomputer, occorrerebbe un tempo pari a 1,02×10^18 anni, ossia 1 miliardo di miliardi di anni.

Per la sua affidabilità e robustezza, AES è stato scelto dal governo degli Stati Uniti come standard per proteggere informazioni classificate fino al livello top secret, che è il livello massimo di segretezza e richiede chiavi a 192 o 256 bit (rispettivamente AES-192 e AES-256).

Tornando a GPG, ipotizziamo di voler criptare un semplice file di testo. L’opzione –cipher-algo ci permette di scegliere un algoritmo di cifratura tra quelli disponibili. Prima che il documento venga crittografato, sarà richiesta una passphrase da cui derivare la chiave privata per il processo di encryption/decryption. Va da sé che più la passphrase è forte e più il rischio che qualcuno possa indovinarla si riduce:

gpg_scr20

A questo punto, se diamo un’occhiata ai file, vedremo un binario con estensione .gpg, che contiene il nostro testo cifrato usando AES-256:

gpg_scr30

Possiamo aprirlo con un editor esadecimale per constatarne l’effettiva illeggibilità:

gpg_scr4

Nel caso in cui sia necessario incollare il contenuto criptato nel body di una mail (supponendo che le parti abbiano condiviso la chiave di persona o tramite un canale sicuro), è opportuno convertire il binario in un formato “user-friendly”, ossia in una sequenza di caratteri stampabili e perfettamente leggibili. A tal proposito, ci viene in aiuto il parametro –armor, che genera un file .asc con un testo codificato in base64:

gpg_scr50

È importante sottolineare che entrambi i file (.gpg e .asc) hanno lo stesso livello di cifratura (AES-256), solo che il primo è in formato binario, mentre il secondo è in formato ASCII.

Per decriptare il documento si usa il comando –decrypt nella seguente sintassi:

gpg_scr60

Con l’opzione –output è possibile specificare un file all’interno del quale scrivere il contenuto in chiaro.

NB: al momento del processo di decrittazione verrà richiesto di inserire nuovamente la passphrase. Qualora sia stata smarrita o dimenticata, sarà del tutto impossibile sbloccare la chiave, e dunque accedere al contenuto del file.

Il primo PC della storia? Era italiano e apparve 12 anni prima dell’Apple II

prg101

Agli inizi degli anni ’60, un piccolo team di giovani progettisti appena entrati in Olivetti, riuscì a fare quello che nessuno prima di loro aveva fatto: creare il primo personal computer della storia. Era la Programma 101 (P101), meglio conosciuta come “Perottina”, dal nome dell’ingegner Pier Giorgio Perotto che coordinò il gruppo di ricerca.

Per capire quanto un’invenzione del genere fosse rivoluzionaria, bisogna tenere presente che i calcolatori elettronici di allora occupavano spazi enormi e si trovavano solo nelle strutture militari, nelle grandi industrie e in alcune università .

L’idea che una macchina programmabile, cioè in grado di ricevere istruzioni ed eseguirle, potesse trovarsi sulla scrivania di chiunque, era impensabile anche per un colosso come la IBM, tanto che nel 1965, quando la P101 fu presentata alla fiera dell’innovazione di New York, molti pensarono a uno scherzo e lo stand dell’Olivetti catalizzò ben presto l’attenzione di curiosi e addetti ai lavori.

In un’epoca in cui la gente comune vedeva con diffidenza l’elettronica e la tecnologia, il successo riscosso dalla Perottina andò oltre le aspettative: i giornali americani la definirono “the first desktop computer of the world” e la NASA decise di acquistarne una decina di esemplari per i suoi studi.

Trattandosi di un elaboratore a tutti gli effetti, dotato di un proprio “linguaggio macchina” e di una propria memoria centrale, la P101 era in grado di gestire operazioni anche complesse, dal calcolo dell’orbita di un satellite alla simulazione del piano di ammortamento, ma l’aspetto forse più originale fu la possibilità di registrare i programmi su una cartolina magnetica che fungeva da memoria di massa.

In questo modo, il computer diventava accessibile a chiunque ne avesse la necessità o anche solo la curiosità, e l’utente poteva scegliere se scrivere le proprie applicazioni o utilizzare quelle preregistrate.

Programmare con la P101

Esempio di un semplice programma che, dato un numero n in input, dove n≥1, stampa n! (si legge “n fattoriale”). Ovviamente, non avendo una P101 a disposizione, ho usato un emulatore che ne simula le funzionalità:

progscrdef

Di seguito, il codice completo dell’algoritmo. Per facilitare la lettura, ho aggiunto dei commenti vicino ad ogni istruzione:

algcode

L’istruzione AW dà inizio a un ciclo che termina con W e viene eseguito n volte. Finchè n>0, ogni volta n decrementa di 1. Se n=0 il ciclo s’interrompe e il programma stampa n! La costante viene generata all’interno del programma tramite l’istruzione speciale A/↑

Breve anatomia di LVM (Logical Volume Management)

Avevo pensato di scrivere un post sullo standard di cifratura LUKS, supportato nativamente dal kernel Linux, che permette di proteggere i dati criptando partizioni di un disco. Prima, però, voglio fare un breve accenno a un altro strumento nativo, che può tornarci utile quando scegliamo di cifrare l’intero sistema: LVM, o Logical Volume Manager.

Per “gestione logica dei volumi” s’intende una forma di allocazione dinamica dello spazio. L’idea di base è quella di superare i limiti imposti dai tradizionali metodi di partizionamento come MBR, “sganciando” il livello logico dal livello fisico e fornendo uno strato di astrazione tra un file-system e i dischi o le partizioni che si utilizzano.

Questo consente di creare i cosiddetti logical volumes (LVs), ognuno dei quali può estendersi su più dispositivi di storage in maniera del tutto trasparente, cioè senza provocare interruzioni del servizio. Un logical volume, infatti, è costruito sopra un’entità che funge da disco rigido virtuale, il volume group (VG), formato da uno o più dispositivi fisici chiamati physical volumes (PVs):

lvmschema

Con LVM, poiché la configurazione reale dei dischi è nascosta dal software, diventa possibile gestire i dati a un livello più alto, unificando lo spazio di archiviazione disponibile sul sistema per definire un numero arbitrario di unità logiche. In questo modo, se un file-system si riempie, un nuovo physical volume (disco o partizione) potrà essere aggiunto al volume group così da espandere facilmente il volume logico.

Esempio:

voglio incrementare le dimensioni della partizione LVM di root. In primo luogo, verifico le informazioni relative allo spazio occupato dal file-system che m’interessa:

dfht111

Lancio i comandi pvsvgs lvs per capire com’è organizzato il mio LVM:

lvmstruct4444

Al momento ho:

  • un physical volume in /dev/mapper/sda5_crypt;
  • un unico volume group chiamato ubuntu-vg;
  • due logical volumes, di cui uno riservato alla partizione di root (quella che voglio espandere) e l’altro riservato alla partizione di swap

Poiché nel volume group non c’è più spazio, dovrò collegare un altro physical volume. Tramite fdisk -l posso vedere il mio nuovo device:

fdisknew1111

A questo punto, vado a creare una partizione con i seguenti comandi:

partalter111

Ora possiamo finalmente inizializzarla come physical volume:

pvcreate111

E allocare spazio aggiungendo il physical volume appena creato al volume group:

volgroupext

Procediamo quindi ad espandere il logical volume, che da 47,52gb passerà a 54,52gb:

lvextend111111111111

E per concludere, andiamo a ridimensionare il file-system affinché possa gestire lo spazio appena ottenuto:

resizefilesys111

Il risultato sarà visibile lanciando il comando df -hT:

dmfilesys