Problemi con questo design di sicurezza per lo storage cloud? Il server non ha nemmeno bisogno di conoscere la password per accedere a qualcuno

0

Ho creato un algoritmo che credo utilizzerò per un servizio di cloud storage che sto sviluppando, se non ci sono problemi o vulnerabilità con esso. È questo insieme a TLS e la sicurezza in avanti implementata. Inoltre, quando effettui il login su un nuovo dispositivo devi confermare tramite il tuo account di posta elettronica.

Per creare un account:

  1. Genera due chiavi casuali, la chiave A e la chiave B. La chiave A viene utilizzata per dimostrare l'identità di chi sta effettuando l'accesso. La chiave B viene utilizzata per crittografare i file con AES-256.

  2. Cifra le due chiavi con AES-256 usando un hash della password dell'utente. Pubblicherò presto una domanda a parte su come creare intenzionalmente un ritardo nella funzione di hashing, per prevenire attacchi di forza bruta.

  3. Invia le chiavi crittografate al server, insieme a un hash SHA-256 della chiave A.

Per accedere:

  1. Scarica le chiavi crittografate dal server.

  2. Decrittografa le chiavi con la password con hash.

  3. Carica la chiave A sul server.

  4. Il server blocca la chiave A e la confronta con l'hash memorizzato. Se i due sono identici, comunica al client che la password è corretta (non che è stata inviata oltre).

  5. Elimina la copia della chiave A in memoria dal server.

Per apportare modifiche ai file:

  1. Accedi utilizzando i passaggi sopra indicati. Il server rifiuterà qualsiasi azione a meno che abbia effettuato l'accesso, ovviamente.

  2. Cifra tutti i file con AES-256 utilizzando la chiave B (archiviata in memoria sul client, mai memorizzata in chiaro sul server) prima di inviare online. Decrittografa tutti i file offline di conseguenza.

Per cambiare la password:

  1. Accedi utilizzando i passaggi precedenti.

  2. Encrypt Key A e Key B (memorizzati in memoria dopo l'accesso) con l'hash della nuova password.

  3. Indica al server di eliminare le chiavi crittografate e di caricare quelle nuove.

Per ripristinare password e chiavi (in caso di violazione):

  1. Accedi. Se non puoi farlo con la password e i passaggi precedenti perché la tua password è stata cambiata, usa un'unità di ripristino (facoltativamente creata quando imposti un nuovo account) con le chiavi memorizzate su di essa.

  2. Scarica tutti i file dal server.

  3. Decifra i file con la chiave B.

  4. Genera due nuove chiavi casuali, quindi cripta le nuove chiavi con la nuova password e caricala, insieme a un hash della nuova chiave A.

  5. Il server memorizza nella cache le chiavi crittografate e l'hash e invia un'email di conferma per reimpostare la password e le chiavi dell'account.

  6. Una volta accettata l'e-mail di conferma, il client inizia a crittografare i file con la nuova chiave B e li carica sul server. Una volta trasferiti tutti i file, il server rimuove i vecchi file.

  7. Tutte le chiavi sono invalidate, la disconnessione dall'account su tutti gli altri dispositivi.

Per favore fammi sapere se ci sono problemi con questo algoritmo o miglioramenti che potrei apportare.

    
posta Phoenix Logan 27.12.2013 - 19:15
fonte

1 risposta

2

Il punto delicato in tutti questi protocolli basati su password è la prevenzione degli attacchi di dizionario offline . Un attacco dizionario è quando l'utente malintenzionato cerca potenziali password; è offline se l'utente malintenzionato può farlo a casa senza interagire con il server originale o l'utente di destinazione. Gli attacchi di dizionario offline tendono a funzionare bene, perché gli utenti sono umani e, quindi, in media, le loro password succhiano molto tempo. L'hashing lento e salato (vedere questa risposta ) può aiutare in una certa misura, ma alla fine non risolverà il problema. Le password sono deboli.

È inevitabile che sul server ci sia abbastanza per eseguire un attacco di dizionario offline. Infatti, se l'autore dell'attacco ottiene una copia completa del contenuto del server, allora può emulare il server sulle proprie macchine. Il server in esecuzione deve in qualche modo stabilire se a un client in arrivo, armato solo della sua password, devono essere consentite operazioni distruttive sui file o meno; pertanto, il server deve essere in grado di distinguere tra una password corretta e una errata. Un utente malintenzionato che emula il server e il client può quindi "provare le password" e per definizione è un attacco di dizionario offline.

Il problema, quindi, è assicurarsi che solo il server abbia questo potere; che i valori che consentono attacchi di dizionario offline non sono inutilmente distribuiti al pubblico in generale. Pertanto, nella tua proposta, ci sono aree vulnerabili . In particolare:

  • La "chiave A e B crittografata con la password" potrebbe consentire di eseguire un attacco di dizionario offline. Poiché questo blob è ottenuto dal login prima del server, chiunque può averlo, incluso l'attaccante. Il formato di crittografia deve essere abbastanza speciale per evitare che venga abusato in quel modo (una descrizione a mano libera è che la decrittazione con la password sbagliata deve ancora sembrare funzionare). I formati di crittografia usuali saranno deboli .

  • Allo stesso modo, ci sono file memorizzati, crittografati con la chiave B. Un utente malintenzionato con le "chiavi crittografate con la password" blob e un file crittografato può utilizzarlo per verificare potenziali password ( prova le password finché la decifratura del file non produce qualcosa che "ha senso"). Ciò implica che i file crittografati non devono essere mostrati a nessuno eccetto l'utente legittimamente autenticato (è necessario l'autenticazione dell'utente per l'accesso in lettura, ma anche per l'accesso in scrittura).

Sarebbe più generico e meno confuso separare le due chiavi A e B: sono in realtà diversi tipi di oggetti e sono usati in modi diversi. Quello che vuoi veramente è il seguente:

  1. Un metodo di autenticazione basato su password, in cui il server non apprende la password dell'utente ma può comunque verificarlo.
  2. Una memoria per i file con crittografia basata su password. Questa memoria utilizza un sistema di crittografia in due fasi: una chiave simmetrica K è crittografata con la password e tutti gli altri file sono crittografati con K (questo accelera le modifiche della password) .

Si noti che la parte relativa all'apprendimento della password dell'utente è in realtà: non l'apprendimento di ciò che viene utilizzato per crittografare effettivamente i file. Il metodo generico sarebbe il seguente: per una data password utente P , calcola f (P) con una propria funzione di hashing della password f ( diciamo, bcrypt o PBKDF2). Estendi il risultato con una funzione di derivazione chiave in due tasti U e V (PBKDF2 include il proprio KDF, altrimenti un KDF economico può essere una semplice invocazione di una funzione hash come SHA-256 se la dimensione dell'output è abbastanza grande da essere suddivisa in U e V ). Il server memorizza h (U) per una qualche funzione di hash h , e V viene usato per crittografare la chiave simmetrica K .

Con questo sistema, il server impara U ma questo non gli dà alcun suggerimento su V , applicando i pregi del KDF (un KDF è, per lo più, un funzione di hash con una dimensione di uscita configurabile). Inoltre, U è ancora dopo la funzione f , quindi U consente solo un attacco lento del dizionario offline, qualcosa che il server potrebbe già ho fatto.

Questo sistema richiede che ogni utente possa ottenere il suo salt prima dell'autenticazione. Questo non è un problema, poiché questo sale è solo un valore casuale. Nota come questo protocollo alternativo rimuove la necessità di un "sistema di crittografia speciale" che non consente un attacco di dizionario offline.

Per i punti extra brownie, usa U come password per TLS-SRP. Ciò garantirà l'autenticazione reciproca tra client e server, in base alla password, senza la necessità di alcun certificato.

    
risposta data 27.12.2013 - 21:15
fonte

Leggi altre domande sui tag