Memorizza le password in forma reversibile - un vero caso d'uso

21

Cosa c'è che non va, pazzo pazzo , non dovresti riuscire a recuperare una password in testo semplice!

Lo so. Ascoltami.

Supponiamo che abbia un servizio simile a Mint.com. Per coloro che non hanno familiarità con Mint, funziona in questo modo:

  1. L'utente si iscrive a Mint.com come se fosse un qualsiasi altro servizio online, fornendo un indirizzo e-mail & parola d'ordine.
  2. Ecco dove le cose si fanno interessanti. L'utente seleziona quindi il nome della propria banca da un menu a discesa e fornisce il nome utente e la password di banking online a Mint.
  3. Qui è dove le cose diventano veramente interessanti. Mint memorizza queste credenziali e le usa per recuperare l'elenco delle transazioni con carta di credito / debito effettuate automaticamente dall'utente - in diversi momenti del giorno. Lo fanno accedendo automaticamente al sito di banking online, utilizzando le credenziali degli utenti (presumibilmente attraverso un emulatore di browser).

Ora ho bisogno di un modo sicuro per proteggere le credenziali di online banking dei miei clienti.

Ecco la grande domanda: Come lo faresti?

Sì, ho già letto questa domanda e questo . Tutte le risposte suggeriscono di utilizzare un metodo di comunicazione più sicuro con la terza parte (l'autenticazione tramite le chiavi API o il passaggio di parametri con hash). A mio parere, ed è solo che - un'opinione - mi sembra un vero caso d'uso in cui ho informazioni incredibilmente sensibili che DEVONO essere disponibili in formato testo - almeno periodicamente durante il giorno.

Fatto interessante: Mint.com ha oltre 10 milioni di utenti

    
posta FloatingRock 09.03.2014 - 21:33
fonte

3 risposte

28

Nel caso in cui hai descritto che stai memorizzando informazioni per conto dell'utente, e non lo stai utilizzando per autenticare l'utente. Quindi, mentre il contenuto di ciò che si sta memorizzando include password (quasi esclusivamente), non si veramente "memorizzare le password" nel senso tradizionale. Stai memorizzando segreti .

Adegua la tua strategia di conseguenza.

Entrambi questi problemi sono risolti; hai solo bisogno di applicare la soluzione corretta. Quando si "memorizza le password" (ovvero, l'autenticazione dell'utente), si passa attraverso l'hashing, il sale, la chiave che si estende, ecc., Che si ha familiarità con. Ma per quanto riguarda la memorizzazione dei segreti .

Prima di tutto, evita se possibile il problema . Questo è il motivo per cui esistono concetti come i token di accesso all'API. Non hai bisogno della mia password di Facebook perché non puoi usarla. Hai bisogno di un token di accesso che Facebook è disposto a darti con il mio permesso.

La prossima soluzione migliore è quella di legare l'accesso all'accesso utente . Le informazioni vengono crittografate utilizzando una chiave derivata dalla password che utilizzi per accedere - che non conosco e non memorizzo. Quindi io (il proprietario del server) non posso accedere ai tuoi dati se non inserisci la tua password.

Questo è popolare perché è potente. In effetti, Windows lo ha fatto per molto tempo, motivo per cui la modifica della password può rendere inaccessibile i file crittografati. È anche il motivo per cui la tua password di Windows è memorizzata in testo normale nella memoria mentre sei loggato. Un accorgimento di implementazione che ti consiglierei di evitare.

Avanti sulla nostra lista, puoi separare i tuoi processi in modo tale che i dati non crittografati non siano mai disponibili su macchine rivolte all'esterno. Punti bonus se è coinvolto un HSM. L'essenza qui è che l'utente fornisce i suoi segreti al server web, che vengono rapidamente crittografati usando la chiave pubblica per qualche dispositivo crittografico segreto che è totalmente inaccessibile perché non è connesso. I semplici segreti vengono immediatamente dimenticati e i dati crittografati vengono poi spediti in un magazzino freddo da qualche parte.

Alla fine i segreti verranno decifrati da qualche altra parte con l'assistenza di quel criptico coso e abituarsi. Solo, il punto in cui questo accade non ha accesso a Internet. O almeno nessun percorso dall'esterno in.

Infine, puoi provare la soluzione di cui sopra, ma fallire miseramente. Dico solo questo perché in realtà tutte le altre soluzioni sono solo variazioni schifose su quelle precedenti: crittografia nel database, utilizzando una password dell'applicazione , memorizzando la password su un altro server, memorizzando i dati su un altro server, salendo la tua chiave di crittografia con [ idea stupida qui ], e così via.

E infine, il mio avvertimento standard per domande come questa si applica. Lo scriverò davvero grande:

The fact that you're asking this question means that you shouldn't do it

Scherzi a parte. Memorizzazione delle credenziali bancarie della gente? Se non capisci in che tipo di problemi ti stai prendendo, se stai chiedendo a Internet suggerimenti su come farlo, se tutte le soluzioni che ho menzionato non erano GIÀ innanzitutto per le opzioni valide solo , quindi non dovresti implementare questo .

Le persone si fidano di te per farlo bene. E non hai intenzione di farlo bene. Non perché non hai fatto le domande giuste, ma perché non hai risolto questo problema abbastanza spesso per capire quali insidie nascoste avrai trascurato. Questa è una cosa difficile: non è difficile fare , ma è difficile non commettere errori.

Non tradire la fiducia dei tuoi clienti mettendoti in testa.

    
risposta data 10.03.2014 - 09:16
fonte
4

Anche se non sono d'accordo con questa pratica, se dovessi mantenere informazioni molto sensibili nel mio server ecco cosa farei:

  • Crea un piccolo demone nello stesso server e richiedi che un operatore umano inserisca una password / chiave all'avvio.
    • Ricava una chiave di crittografia simmetrica e una coppia di chiavi asimmetriche da essa.
  • Mantieni questi tasti solo sulla RAM, evita lo swap .
  • Quando un utente vuole inviare le informazioni sensibili al server, chiedigli di crittografarlo sul browser stesso usando la chiave pubblica (in modo che solo il demone possa leggerlo). Chiedi al demone di crittografarlo utilizzando la chiave simmetrica e torna al server web principale, che può ora memorizzarlo.
  • Quando il sistema vuole fare qualcosa con le informazioni sensibili, passa i dati crittografati al demone. Dovrebbe quindi decifrare e idealmente usarlo subito (ad esempio, effettuare la richiesta di terze parti - e non registrare nulla da nessuna parte), cancellare il testo in chiaro e restituire solo la risposta (cioè il server web principale non "vede" il testo in chiaro in qualsiasi momento).

Ovviamente dovresti usare qualsiasi pratica di sicurezza complementare possibile, ma il nocciolo di questa tecnica è che solo gli aggressori con accesso alla macchina live - in grado di leggere i contenuti della RAM di un altro processo - possono recuperare i dati sensibili in testo semplice. Oppure se gli autori degli attacchi possono inserire il proprio codice nel server, quindi al successivo riavvio l'operatore immette la password al daemon loro . Se possono semplicemente inviare comandi arbitrari al demone, saranno in grado di fare tutto ciò che il demone può fare (cioè leggere i dati ottenuti da quelle credenziali, ma non le credenziali stesse, né eseguire azioni che il demone non è stato programmato per eseguire) .

Detto questo, se 10 milioni di idioti non avessero fatto affari con me, probabilmente mi sarei potuto permettere di assumere i migliori professionisti della sicurezza, invece di fare affidamento solo sulla mia conoscenza (come faccio ora). Che potrebbe impedire al mio sistema di essere l'anello più debole, nonostante la sua attrattiva per gli aggressori. Tienilo a mente prima di fare cose ambiziose che, sebbene potenzialmente utili, potrebbero metterti nei guai se quando le cose vanno male.

    
risposta data 10.03.2014 - 08:41
fonte
2

Non vorrei, a meno che non fossi assolutamente sicuro che nessuno sarebbe in grado di entrare nel mio database, preferirei che le informazioni fossero archiviate sui dispositivi dell'utente, quindi il mio servizio non sarebbe responsabile per eventuali perdite di dati. Ma se dovessi farlo ...

Quando un utente crea un account, genererei una chiave AES-256 (chiamiamola storage_key ), quindi crittografare quella chiave con una chiave derivata dalla password dell'utente (chiamiamola user_key ) usando qualche solido KDF (scrypt, bcrypt, PBKDF2 ...) e lo memorizza come encrypted_storage_key insieme a salt, iterations e altri parametri usati da KDF per ricavare user_key con l'account dell'utente.

Quindi il processo di inserimento / lettura dei dati sarà simile a:

  1. L'utente inserisce una password.
  2. Usando il KDF selezionato e i parametri memorizzati si ottiene user_key .
  3. Decifra lo encrypted_storage_key memorizzato con user_key e ottieni l'originale storage_key .
  4. Utilizza questo storage_key per crittografare / decrittografare i dati sensibili.
  5. Non tenere in memoria storage_key in giro più a lungo di quanto potrebbe essere necessario e non memorizzarlo mai e poi mai in tale forma.

Ovviamente, per questo sistema di sicurezza è di fondamentale importanza proteggere la "linea" attraverso la quale l'utente inserisce la sua password (ad es. SSL / TLS come minimo se stiamo parlando di un sito web ) - se qualcuno è in grado di ottenere la password originale, l'intero schema cade a pezzi.

    
risposta data 09.03.2014 - 22:04
fonte

Leggi altre domande sui tag