Crittografia di backup sicura con OpenSSL

13

Lo so, il consiglio generale è "tieni le mani fuori dalla criptografia". E il modo standard per crittografare i dati di backup in modo sicuro sarebbe utilizzare GnuPG. Tuttavia, per un esercizio piuttosto accademico, mi piacerebbe pensare a un protocollo che funzioni solo con gli strumenti standard di OpenSSL (cioè, dgst, enc, rsautl & Co) richiamati da una shell POSIX.

Lo scenario include un sistema più o meno affidabile su e da cui vengono creati i backup - questo potrebbe e. g. essere un mail o un file server. Poi c'è uno storage che non è affidabile al 100% (ad esempio, un cloud storage o un server di backup non completamente sotto il mio controllo). Quindi lo scopo della crittografia è proteggere la riservatezza e l'integrità dei dati mentre sono archiviati nella memoria non sicura. Questa protezione dovrebbe anche funzionare nel caso in cui il sistema di fiducia venga compromesso, almeno per i dati memorizzati prima che il sistema attendibile venisse compromesso.

Quindi ecco una sorta di protocollo che dovrebbe soddisfare i criteri sopra menzionati:

Passaggio 1: coppia di chiavi RSA

Questo passaggio deve essere eseguito solo una volta. È necessaria una coppia di chiavi RSA. Questa coppia di chiavi non deve essere creata sul sistema "fidato", ma su una scatola veramente affidabile (ad esempio una stazione di lavoro affidabile o dovunque ti fidi di mantenere il tuo keyring GPG). Poiché la chiave privata è necessaria solo per il ripristino, non deve mai entrare nei reami del sistema attendibile o della memoria non attendibile. La dimensione della chiave deve essere 4096 bit o superiore (ne parleremo più avanti). OpenSSL di solito offre la generazione e la separazione delle chiavi con questi comandi:

EDIT: switched to PKCS#8 for the keys, being probably more resistant to brute force attacks

openssl genpkey -aes-256-cbc -algorithm RSA -pkeyopt 'rsa_keygen_bits:8192' -out private.key
openssl pkey -in private.key -out public.key -pubout

Passaggio 2: Genera segreti di sessione

Per ogni processo di crittografia, devono essere generati segreti dedicati (chiave, vettore di inizializzazione e sale):

EDIT: removed salt as per Ctulhu's comment

key=$(openssl rand -hex 32)
iv=$(openssl rand -hex 16)
hmacpw=$(openssl rand -base64 48)

Nota: sono consapevole che questo avrà i segreti non protetti nella memoria della macchina affidabile. Tuttavia, se un utente malintenzionato ha accesso alla macchina in modo da poter scremare la memoria del processo di backup, probabilmente ha già accesso ai dati da proteggere con questi segreti.

Passaggio 3: comprimi e crittografa

I dati devono essere compressi prima della crittografia. La compressione è necessaria comunque, quindi ritengo una buona idea farlo prima di crittografare i dati:

EDIT: removed salt as per Ctulhu's comment

data-generator | xz -zc | openssl enc -e -aes-256-ctr -K $key -iv $iv -out message.enc

Passaggio 4: Genera HMAC e impacchetta i tasti

L'ultimo passo sarebbe quello di generare un HMAC dei dati appena crittografati e comprimerlo insieme con i segreti della sessione in un file crittografato RSA, utilizzando la chiave pubblica per la crittografia:

EDIT: removed salt as per Ctulhu's comment

hmac=$(openssl dgst -sha512 -hmac $hmacpw -hex message.enc | sed 's/^.*=[[:space:]]//g')
echo "${key}:${iv}:${hmacpw}:${hmac}" | openssl rsautl -inkey public.key -pubin -encrypt -out message.key

E qui diventa ovvio perché la chiave RSA doveva essere così grande: le cifre esadecimali nelle stringhe di shell sono contate come un byte ciascuna, non mezzo un byte. Pertanto, la dimensione della stringa di tasti riassume (2x32 + 2x16 + 64 + 128 + 5) = 293 byte = 2344 bit.

Ancora una volta, sono consapevole che esporre i segreti su una linea di comando è generalmente una cattiva idea, ma date le circostanze, non vedo come ciò comprometterebbe la riservatezza o l'integrità dei dati che sono disponibili in testo normale su tale sistema, dove un aggressore potrebbe molto più facilmente compromettere la loro privacy o integrità. Tuttavia, se volessi davvero implementarlo, preferirei usare named pipe per evitare che i segreti si presentino nella lista dei processi.

Ora le mie domande:

  1. Cosa mi sono perso? Vedi qualche difetto o potenziale vettore di attacco che non ho ancora notato?
  2. Sarebbe più sicuro creare una firma con openssl dgst -sha512 -sign private.key -out message.sig message.enc , dato che questo richiederebbe la chiave privata per risiedere sul sistema più o meno affidabile?
posta Daemotron 12.08.2015 - 12:45
fonte

1 risposta

1
  1. Per la domanda su cosa potresti aver perso:

Nel momento in cui hai crittografato i dati sul server, puoi utilizzare rsync per sincronizzare in modo sicuro i dati sul backup.

rsync -aHSv --del --progress ~/<encrypted-data> user@remote-backup-server:/<destination-directory>./ -n

L'uso di --del è quello di rimuovere le cose vecchie nella destinazione remota (puoi tranquillamente rimuovere quell'opzione se vuoi conservare tutta la cronologia).

  1. Per la domanda sulla sicurezza:

Il vantaggio di fare cose con rsync è che puoi proteggere backup server firewall per lavorare con solo qualche IP su qualche ports e usare il tuo RSA Keys con ~/.ssh/authorized_keys

  1. OpenSSL o LibreSSL?

Penso che quel punto potrebbe essere interessante da scavare come spiegato su security.stack

    
risposta data 06.11.2016 - 20:08
fonte

Leggi altre domande sui tag