Domanda

Sto scrivendo un app che scopo principale è quello di mantenere la lista di utenti acquisti.

Vorrei assicurare che anche io come sviluppatore (o chiunque con piena l'accesso al database) non riusciva a capire quanti soldi un determinata persona ha speso o quello che ha comprato.

I inizialmente si avvicinò con il seguente schema:

    --------------+------------+-----------
    user_hash     | item       | price
    --------------+------------+-----------
    a45cd654fe810 | Strip club |     400.00
    a45cd654fe810 | Ferrari    | 1510800.00
    54da2241211c2 | Beer       |       5.00
    54da2241211c2 | iPhone     |     399.00
  • utente accede con username e password.
  • Dal user_hash password di calcolare (possibilmente con salatura, ecc.).
  • Utilizza l'hash per l'accesso degli utenti dati con normale query SQL-.

Gli utenti abbastanza dato, dovrebbe essere quasi impossibile dire quanto soldi un particolare utente ha speso da solo sapendo il suo nome.

E 'una cosa sensata da fare, o sono del tutto insensato?

È stato utile?

Soluzione

Il problema è che se qualcuno ha già pieno accesso al database allora è solo una questione di tempo prima che collegano i record a particolari persone. Da qualche parte nel database (o nell'applicazione stessa) si dovrà fare il rapporto tra l'utente e gli elementi. Se qualcuno ha accesso completo, allora avranno accesso a tale meccanismo.

Non c'è assolutamente alcun modo di prevenire questo.

La realtà è che avendo accesso completo siamo in una posizione di fiducia. Ciò significa che i responsabili aziendali devono fiducia che, anche se è possibile vedere i dati, non si agirà in alcun modo su di esso. Questo è dove le piccole cose come l'etica entrano in gioco.

Ora, detto questo, un sacco di aziende separare lo sviluppo e la produzione personale. Lo scopo è quello di eliminare lo sviluppo di avere un contatto diretto con live: i dati (ad esempio reale). Ciò comporta una serie di vantaggi con sicurezza e affidabilità dei dati essendo in cima al mucchio.

L'unico vero inconveniente è che alcuni gli sviluppatori credono di non poter risolvere un problema senza l'accesso alla produzione. Tuttavia, questo semplicemente non è vero.

personale

Produzione poi sarebbero gli unici ad avere accesso ai server in tempo reale. Essi saranno tipicamente controllati in misura maggiore (storia criminale e di altri controlli di fondo), che è commiserare il tipo di dati che si devono proteggere.

Il punto di tutto questo è che questo è un problema personale; e non uno che può realmente essere risolto con mezzi tecnici.


Aggiorna

Altri qui sembrano mancare un pezzo molto importante e vitale del puzzle. Vale a dire, che i dati vengono immessi nel sistema per un motivo. Che la ragione è quasi universalmente in modo che possa essere condiviso. Nel caso di una nota spese, che i dati viene inserito in modo che la contabilità possa sapere chi arretrati.

Il che significa che il sistema, a un certo livello, dovrà corrispondere gli utenti e gli elementi senza che la persona di immissione dei dati. (Vale a dire: un addetto alle vendite) viene registrato in

E quando i dati devono essere legati insieme, senza tutte le parti coinvolte in piedi di digitare un codice di sicurezza per "rilasciare" i dati, quindi un DBA sarà assolutamente in grado di esaminare i registri di query di capire chi è chi. E molto facilmente potrei aggiungere indipendentemente dal numero di hash marchi si vuole buttare in esso. Triple DES non sarà risparmiare sia.

Alla fine della giornata tutto quello che hai fatto è lo sviluppo make più difficile con assolutamente prestazione di sicurezza zero. Non posso sottolineare abbastanza: l'unico modo per nascondere i dati da un DBA sarebbe per entrambi 1. che i dati a solo essere accessibile da parte della persona che è entrato molto o 2. per esso di non esistere in primo luogo.

Per quanto riguarda l'opzione 1, se l'unica persona che può sempre accedervi è la persona che ha di esso .. beh, non v'è alcun punto per essere in un database aziendale.

Altri suggerimenti

Ho paura che se l'applicazione può collegare una persona ai suoi dati, qualsiasi sviluppatore / amministratore può.

L'unica cosa che si può fare sta rendendo più difficile da fare il collegamento, per rallentare lo sviluppatore / admin, ma se si fanno più difficile per gli utenti di collegamento ai dati, si renderà più difficile per il server anche.


Idea sulla base di @no idea:

Si può avere un classico login utente / password per l'applicazione (password hash, o qualsiasi altra cosa), e uno speciale "pass" utilizzata per mantenere la protezione dei dati. Questa "pass" non sarebbe stato memorizzato nel database.

Quando il registro client nell'applicazione avrei dovuto fornire utente / password / pass. L'utente / password viene verificata con il database, e il passo sarebbe stato utilizzato per i dati di carico / scrittura.

Quando è necessario scrivere i dati, si fa un hash del vostro "/ passare username" coppia, e conservarla come una chiave che collega il client per i dati.

Quando è necessario caricare i dati, si fa un hash del vostro "/ passare username" coppia, e caricare tutti i dati corrispondenti a questi hash.

In questo modo è impossibile fare un collegamento tra i dati e l'utente.

In un'altra mano, (come ho detto in un commento a @no) attenzione di collisioni . Inoltre, se l'utente scrivere un cattivo "pass" non si può controllare.


Aggiornamento:. Per l'ultima parte, ho avuto un'altra idea, è possibile memorizzare nel database un hash del vostro "/ password pass" coppia, in questo modo è possibile verificare se il "pass" è a posto

  1. Crea una tabella utenti:
    1. user_id: una colonna di identità (auto-generato id)
    2. nome utente
    3. Password: assicurarsi che sia hash
  2. Creare una tabella prodotto simile nel tuo esempio:
    1. user_hash
    2. voce
    3. prezzo

L'user_hash sarà basato off di id_utente che non cambia mai. Username e password sono liberi di cambiare, se necessario. Quando l'utente accede, si confrontano username / password per ottenere l'user_id. È possibile inviare la schiena user_hash al cliente per tutta la durata della sessione, o un crittografato versione / indiretta della hash (potrebbe essere un ID di sessione, in cui il server memorizza l'user_hash nella sessione).

Ora avete bisogno di un modo per hash l'user_id in user_hash e tenerlo protetto.

  1. Se lo si fa sul lato client come @no suggerito, il cliente ha bisogno di avere id_utente. Grande buco di sicurezza (soprattutto se si tratta di una web app), hash può essere facilmente essere manomesso e l'algoritmo è liberamente disponibile al pubblico.
  2. Si potrebbe avere come una funzione nel database. Pessima idea, dal momento che il database ha tutti i pezzi per collegare i record.
  3. Per i siti web o client / server applicazioni che si potrebbe avere sul vostro codice lato server. Molto meglio, ma poi uno sviluppatore ha accesso alla algoritmo di hash e di dati.
  4. Avere un'altra scrittura sviluppatore l'algoritmo di hashing (che non si ha accesso a) e bastone in su un altro server (che anche voi non avete accesso a) come un servizio TCP / web. Il tuo codice lato server sarebbe quindi passare l'ID utente e ottenere un back hash. Non avreste l'algoritmo, ma è possibile inviare tutti gli ID utente attraverso per ottenere tutti i loro hash indietro. Non un sacco di vantaggi per 3 #, anche se il servizio potrebbe avere la registrazione e tale da cercare di ridurre al minimo il rischio.
  5. Se è semplicemente un'applicazione client-database, si hanno solo scelte # 1 e 2. Vorrei suggerire di aggiungere un altro strato [attività] che è lato server, separato dal server di database.

Modifica Questo si sovrappone alcuni dei punti precedenti. Avere 3 server:

  • del server di autenticazione : Impiegato A ha accesso. Mantiene tabella utente. Ha servizio web (con comunicazioni criptate) che prende combinazione utente / password. Hash delle password, guarda in alto id_utente nella tabella, genera user_hash. In questo modo non può semplicemente inviare tutti user_ids e tornare gli hash. Bisogna avere la password, che non è memorizzato da nessuna parte ed è disponibile solo durante il processo di autenticazione.
  • server di database principale : Impiegato B ha accesso. Solo negozi user_hash. No userid, nessuna password. È possibile collegare i dati utilizzando l'user_hash, ma l'informazioni utente reale è da qualche altra parte.
  • server del sito web : Impiegato B ha accesso. Ottiene informazioni di login, passa al server di autenticazione, ottiene hash indietro, poi dispone informazioni di login. Mantiene hash in sessione per la scrittura / esecuzione di query al database.

Quindi dipendente A è ID_utente, nome utente, password e l'algoritmo. Impiegato B ha user_hash e dati. A meno che non modifica dipendente B il sito web per memorizzare l'utente / password grezzo, non ha modo di collegare alle reali utenti.

Utilizzando SQL profiling, Impiegato A otterrebbe user_id, username e password hash (dal user_hash viene generato più avanti nel codice). Impiegato B otterrebbe user_hash e dati.

L'unico modo per garantire che i dati non possono essere collegati alla persona a cui appartiene è quello di non registrare le informazioni di identità in primo luogo (rendere tutto anonimo). In questo modo, però, molto probabilmente rendere il vostro app inutile. È possibile rendere questo più difficile da fare, ma non si può rendere impossibile.

La memorizzazione dei dati degli utenti e le informazioni di identificazione in database separati (ed eventualmente su server separati) e che collega i due con un numero di identificazione è probabilmente la cosa più vicina che si può fare. In questo modo, hanno isolato i due insiemi di dati il ??più possibile. È comunque necessario mantenere quel numero ID da collegamento tra di loro; in caso contrario, si sarebbe in grado di recuperare i dati di un utente.

Inoltre, non mi consiglia di utilizzare una password hash come un identificatore univoco. Quando un utente cambia la password, si dovrebbe quindi passare attraverso e aggiornare tutti i database per sostituire gli ID vecchia password hash con quelli nuovi. Di solito è molto più facile da usare un ID univoco che non si basa su nessuna delle informazioni dell'utente (per contribuire a garantire che rimanga statico).

Questo finisce per essere un problema sociale, non è un problema tecnologico. Le migliori soluzioni saranno una soluzione sociale. Dopo l'indurimento i sistemi per la guardia contro l'accesso non autorizzato (hacker, ecc), si avrà probabilmente ottenere una migliore distanza in miglia lavorando sulla creazione di fiducia con gli utenti e implementare un sistema di politiche e procedure in materia di sicurezza dei dati. Includere sanzioni specifiche per i dipendenti che abusano informazioni sui clienti. Dal momento che una singola violazione della fiducia del cliente è sufficiente per rovinare la vostra reputazione e guidare tutti gli utenti di distanza, la tentazione di abuso questi dati da coloro che hanno accesso "top-level" è meno di quanto si potrebbe pensare (dopo il crollo della società in genere supera qualsiasi guadagno).

Tenete a mente che, anche senza in realtà la memorizzazione della persona informazioni di identificazione da nessuna parte, semplicemente associando informazioni sufficienti tutti con la stessa chiave potrebbe consentire di capire l'identità della persona associata a determinate informazioni. Per un semplice esempio, è possibile richiamare la strip club e chiedere quale cliente ha guidato una Ferrari.

Per questo motivo, quando si de-identificare le cartelle cliniche (per scopi di ricerca e simili), è necessario rimuovere i compleanni per persone con più di 89 anni (perché la gente che età sono abbastanza raro che una data di nascita specifica potrebbe puntare a un sola persona) e rimuovere qualsiasi geografica codifica che specifica un'area contenente meno di 20.000 persone. (Vedere http://privacy.med.miami.edu/glossary/xd_deidentified_health_info.htm )

AOL ha trovato il modo duro quando pubblicarono la ricerca dei dati che le persone possono essere identificati solo conoscendo quello che le ricerche sono associati ad una persona anonima. (Vedere http://www.fi. muni.cz/kd/events/cikhaj-2007-jan/slides/kumpost.pdf )

Sembra che tu abbia ragione in pista con questo, ma si sta pensando poco più (o semplicemente non lo capisco)

Scrivi una funzione che crea una nuova stringa in base all'ingresso (che sarà un nome utente o qualcosa d'altro che non posso cambiare gli straordinari)

Utilizza la stringa restituita come sale quando si costruisce l'hash utente (di più, vorrei usare l'userID o il nome utente come input per il costruttore di hash, perché non cambierà come password o e-mail degli utenti)

Associare tutte le azioni dell'utente con l'hash utente.

Nessuno con accesso al database solo in grado di determinare che cosa diavolo l'utente hash media. Anche un tentativo di bruta forzandolo provando seme differente, combinazioni sale finirà inutile perché il sale è determinata come una variante del nome utente.

Credo che tu hai risposto domanda proprio con il tuo post iniziale.

In realtà, c'è un modo che si potrebbe fare quello che stai parlando ...

Si potrebbe avere l'utente digita il suo nome e la password in una forma che esegue uno script puramente sul lato client che genera un hash basato sul nome e pw. Questo hash viene utilizzato come un ID univoco per l'utente, e viene inviato al server. In questo modo il server sa solo l'utente da hash, non per nome.

Per questo al lavoro, però, l'hash dovrebbe essere diverso dal normale hash della password, e l'utente verrà richiesto di inserire il proprio nome / password un tempo supplementare prima che il server avrebbe alcuna 'memoria' di ciò che persona ha acquistato.

Il server poteva ricordare quello che la persona ha acquistato per tutta la durata della loro sessione e poi 'dimenticare', perché il database conterrebbe alcun legame tra gli account utente e le informazioni sensibili.

modifica

In risposta a quelli che dicono hashing sul client è un rischio per la sicurezza: Non è se lo fai bene. Si deve presumere che un algoritmo di hash è noto o conoscibile. Dire il contrario equivale a "sicurezza attraverso l'oscurità." Hashing non comporta alcun chiavi private, e gli hash dinamiche potrebbero essere utilizzati per evitare la manomissione.

Per esempio, si prende un generatore di hash come questo:

http://baagoe.com/en/RandomMusings/javascript/Mash.js

// From http://baagoe.com/en/RandomMusings/javascript/
// Johannes Baagoe <baagoe@baagoe.com>, 2010
function Mash() {
  var n = 0xefc8249d;

  var mash = function(data) {
    data = data.toString();
    for (var i = 0; i < data.length; i++) {
      n += data.charCodeAt(i);
      var h = 0.02519603282416938 * n;
      n = h >>> 0;
      h -= n;
      h *= n;
      n = h >>> 0;
      h -= n;
      n += h * 0x100000000; // 2^32
    }
    return (n >>> 0) * 2.3283064365386963e-10; // 2^-32
  };

  mash.version = 'Mash 0.9';
  return mash;
}

Vedere come i cambiamenti n, ogni volta che si hash di una stringa si ottiene qualcosa di diverso.

  • Hash il nome utente + password utilizzando un normale algo hash. Questo sarà lo stesso come la chiave della tabella 'segreto' nel database, ma corrisponderà nient'altro nel database.
  • Aggiungere il passaggio hash per il nome utente e hash con l'algoritmo di cui sopra.
  • Base-16 codifica var n e aggiungerla nella hash originale con un carattere delimitatore.

Questo creerà un hash univoco (sarà diverso ogni volta), che può essere controllato dal sistema contro ogni colonna nel database. Il sistema può essere impostato da consentire un particolare hash univoco solo una volta (per esempio, una volta l'anno), prevenendo attacchi MITM, e nessuna delle informazioni dell'utente viene passato attraverso il filo. A meno che non mi manca qualcosa, non c'è nulla insicuro su questo.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top