2011-08-30 10 views
7

Obiettivo:Proteggi le PII nel database delle app Web crittografando con una chiave pubblica abbinata a una chiave privata protetta dalle password degli utenti?

mi piacerebbe per consentire agli utenti di creare domande e raccogliere informazioni da altri utenti in una web app personalizzato (PHP/MySQL in un ambiente di hosting puntellato) e proteggere i dati raccolti.

Background:

Le domande predefinite che tutti gli utenti rispondono sono abbastanza da non poter essere interpretati come dati personali (PII) in generale, limitando così la mia responsabilità per proteggerlo, ma gli utenti che creare il proprio le domande probabilmente richiederanno le PII che poi diventeranno una responsabilità.

Quello che mi piacerebbe fare è proteggere queste informazioni in modo tale che se l'account di hosting o il database fossero compromessi (o entrambi!), Le PII non sarebbero recuperabili senza una quantità significativa di lavoro, e persino quindi, solo una piccola parte sarebbe teoricamente recuperabile.

Soluzione proposta:

Supponendo built-in AES_ENCRYPT()/AES_DECRYPT() funzioni sono utilizzate per cifrare il tavolo PII, la passphrase dovrebbe essere memorizzato nel account di hosting, quindi, se l'account di hosting sono stati compromessa, i dati di MySQL potrebbe essere facilmente letto.

Poiché le password degli utenti sono ben protette (hash con sale), sto pensando di acquisire la loro password in chiaro durante l'autenticazione, crittografandola e memorizzandola nella sessione PHP fino a quando l'utente non si disconnette.

Una combinazione di chiave pubblica/privata verrà creata per ciascun utente con la chiave privata protetta da password con la password dell'utente + sale.

Quindi, quando i dati PII basati sulle domande personalizzate dell'utente vengono aggiunti al DB, la chiave pubblica dell'utente viene utilizzata per crittografare le PII raccolte tramite l'app. Quando i dati vengono letti (solo quando l'utente ha effettuato l'accesso), i dati non vengono crittografati con la chiave privata dell'utente (che viene sbloccata con la password + sale).

I benefici che vedo sono:

  1. nella peggiore delle ipotesi, in cui i server completamente compromessi, codice di applicazione viene letto per trovare le chiavi di crittografia, i file di sessione PHP vengono decifrati per trovare le password degli utenti, poi le voci nella tabella PII associata a quell'utente vengono decifrati, quindi solo le PII raccolte dalle domande degli utenti attualmente connessi potrebbero essere ripristinate. Qualsiasi utente non connesso sarebbe sicuro.
  2. anche il DBA o simili non sono in grado di leggere le PII.

I svantaggi vedo sono:.

  1. password degli utenti sono memorizzati in una forma recuperabile mentre sono connessi in
  2. utenti che dimenticano la loro password sarebbe perdere l'accesso ai propri dati.
  3. ogni bit relativamente piccolo di dati occuperà molto più spazio nel DB a causa della crittografia.

La mia domanda: C'è un modo migliore per farlo?

+0

È quasi impossibile garantire la protezione non appena il server viene compromesso. Non appena qualcuno ha accesso al codice php, può facilmente modificare il codice per scrivere tutte le password (o keypairs) in un file di testo in chiaro all'accesso. Non appena il sale è conosciuto (o noto come è costruito), l'hash non è risparmiato per la protezione. – Fge

+0

Sì, finché la violazione non viene scoperta, è possibile acquisire le password. L'idea è contenimento e perdita minimizzata. Almeno alcuni dati sarebbero comunque protetti perché, si spera, la violazione verrebbe scoperta abbastanza rapidamente e non tutti gli utenti effettuerebbero il login entro quel periodo di tempo. –

+0

Che cosa si desidera memorizzare esattamente nella sessione PHP? Non vedo perché hai bisogno di una chiave di crittografia aggiuntiva in memoria se decifri solo la chiave privata all'accesso. –

risposta

6

Vedo un numero di problemi con questo design dal punto di vista della sicurezza. Prima di tutto le password non devono mai essere crittografate, si tratta di una vulnerabilità identificata da CWE-257.

Ulteriori informazioni su MySQL AES_ENCRYPT() sono spazzatura completa per più motivi. Si utilizza la modalità EBC, ed ecco un buon esempio del perché questo è una schifezza:

Immagine originale:

enter image description here

modalità EBC (che è AES_ENCRYPT() uso di ciò che MySQL):

enter image description here

Ma se il database in cui è stato compromesso l'aggressore sta per sconfiggere AES_ENCRYPT() abilitando lo query log.

L'utilizzo della password dell'utente per la crittografia deve essere evitato, si dovrebbe utilizzare un nonce crypgoraphic. Se usi una password assicurati di usare una funzione String2Key. È inoltre necessario utilizzare la modalità CBC o CMAC con uno random iv. Non vedo davvero come la crittografia asimmetrica possa aiutare. La crittografia asimmetrica è molto lenta e richiede molta memoria. I dati che protegge sono resi meno sicuri quando l'utente malintenzionato controlla il messaggio perché è possibile confrontare i messaggi di testo crittografati. Ecco perché un IV is important casuale, e nel mondo asimmetrico non si dispone di questo livello di protezione.

Generazione chiave dovrebbe essere simile: $key=string2key($base_nonce.$salt.$user_password)

assicurarsi che l'uscita della funzione string2key è la stessa dimensione come il vostro spazio delle chiavi. Quindi, aes 128 ha bisogno di una chiave a 128 bit. Ogni password deve avere il proprio $salt e lo $base è un nonce crittografico memorizzato nel file di testo. (Un utente malintenzionato dovrebbe leggere questo file prima di poter rompere la chiave, se questo valore è grande come 128 bit quindi è un punto controverso.) Ogni messaggio ha bisogno del proprio $iv e questo valore deve anche essere un nonce crittografico (simile a un sale). Vorrei generare il $salt, $iv e $base_nonce da /dev/urandom. L'IV può essere memorizzato in testo normale in una colonna del tuo database insieme al testo cifrato.

Da un punto di vista legale, anche se si crea un sistema crittografico sicuro, si hanno ancora problemi con le minacce interne e se il server è completamente compromesso, tutti i dati saranno comunque compromessi. Questo in realtà non è un problema di ingegneria.

La migliore difesa contro una minaccia legale è un forte Termini e Condizioni scritto da un avvocato esperto.

+0

+1 per questa bella dimostrazione delle debolezze di EBC e dei consigli per quanto riguarda le minacce legali. Sono comunque abbastanza sicuro che OP non voglia usare 'AES_ENCRYPT' e la sua controparte, perché afferma nel suo post che" se l'account di hosting fosse compromesso, i dati potrebbero essere facilmente letti. ", Che vuole prevenire usando uno schema di crittografia/decrittografia asimmetrico. –

+0

@Niklas yeah vuole usare la crittografia asimmetrica che a detta di tutti è un'idea peggiore. – rook

0

Una preoccupazione che avrei è la seguente. La parte "tutti gli utenti che non hanno effettuato l'accesso sarebbero sicuri" la parte è troppo ottimistica. Proteggendo la chiave privata con la password dell'utente, ti apri a vari attacchi brute-force. Non solo per le sessioni in corso, ma per tutti. Uno efficace è quello di enumerare semplicemente le prime 100 password comuni, per esempio, e provarle solo contro tutti gli utenti. L'attaccante è tenuto a scoprire alcune chiavi. (Suppongo che tu stia memorizzando sale salt per utente con il record utente, che l'utente malintenzionato può vedere, oppure che tu abbia un sale segreto che l'utente malintenzionato è stato in grado di ottenere attraverso il compromesso.)

+0

I modi migliori per prevenire il cracking della password sono algoritmi hash iterati (un attacco a forza bruta non sarà praticabile se si possono controllare solo 10 password/secondo) e soprattutto forzare una policy password rigida sui propri utenti (lunghezza minima, necessita di caratteri speciali/numeri/maiuscole/minuscole). Non sottovalutare la potenza dei moderni cracker della GPU, che possono facilmente controllare centinaia di milioni di password con hash deboli al secondo (e questa è solo una singola scheda grafica). –

+0

Sì, la politica di password rigorosa è di grande aiuto. Senza questo, anche le 10 password/secondo sono probabilmente abbastanza veloci da scoprire password ad alta frequenza. Anni fa ero il sysadmin per un sistema in cui tutte le password erano memorizzate come testo in chiaro, e ho sicuramente visto varie password che continuavano a venire (gli utenti erano noti per essere unici): "password", "p @ ssword", "orange" , "ilove [some_name]", "f * ckyou" e varianti, "fiore", 1337 versioni di parole comuni, ecc. Lo stretching chiave aiuta anche se. –

Problemi correlati