Ho creato un'API che consente agli utenti di inviare dati crittografati per essere archiviati nel cloud. Per recuperare i loro dati, l'API richiede all'utente di fornire solo l'ID oggetto MongoDB che gli viene fornito quando ha inviato i propri dati, più l'hash SHA1 della password che hanno usato per crittografare i dati. Ho scelto di utilizzare sia l'ID oggetto che l'hash della password come chiave univoca per impedire agli utenti di richiedere dati sull'API, poiché ID oggetto diversi non sono complessi e facili da indovinare.
Ora ho passato il metodo hash da SHA1 a bcrypt in quanto è più sicuro, ma questo ha presentato un problema. Poiché bcrypt genera sempre un sale diverso, l'hash è sempre un significato diverso Non posso più utilizzare l'hash generato per identificare i dati dell'utente nel database, a meno che non costringa l'app a utilizzare lo stesso salt ogni volta che genera un hash bcrypt. Nota: se utilizzo una costante salt, sarà nota al pubblico in quanto il codice sorgente è open source.
La mia domanda è, se uso una costante salt con bcrypt per generare hash delle password, questo rende gli hash più facili da decifrare che usare SHA1 come ero originariamente, e se non è ancora un approccio poco pratico alla creazione di hash delle password sicure ?
In alternativa, esiste un approccio migliore per specificare una chiave univoca per i dati dell'utente nel db senza chiedere all'utente ulteriori informazioni?
Modifica: nel tentativo di mantenere la domanda il più semplice possibile, mi sono reso conto che non ho davvero fornito un contesto sufficiente per il motivo per cui ho scelto l'approccio che ho, quindi ecco un po 'di più informazioni per sperare che le cose siano più chiare e che le persone possano fornire una risposta il più precisa possibile.
L'intenzione è creare un servizio sicuro e anonimo per supportare l'app, che può essere eseguito da chiunque, ovunque. L'app e l'API sono open source e quindi chiunque desideri fornire il proprio spazio server per altri utenti dell'app può eseguire la propria istanza dell'API. Gli utenti dell'app possono quindi indirizzarlo all'URL dell'API di loro scelta, ciò consente loro di utilizzare qualsiasi istanza dell'API ospitata dal pubblico o persino ospitare un'istanza sul proprio server che solo loro possono utilizzare.
Poiché i dati dell'utente potrebbero essere seduti su qualsiasi server pubblico, è importante che i dati siano crittografati sul lato client e che l'utente non invii mai la password cleartext sul cavo, nel caso in cui il proprietario del server API (o chiunque altro) desideri per decifrare i dati utente ospitati. Il servizio è anonimo per ragioni di sicurezza e convenienza, quindi l'utente dell'applicazione non deve fornire un indirizzo email o altre informazioni identificative, basta fare clic su un pulsante nell'app e i loro dati sono crittografati con la loro password, che viene inviata a l'API con la loro password con hash:
Esempio di post del corpo:
{
"data":"DWCx6wR9ggPqPRrhU4O4oLN5P09onApoAULX4Xt+ckxswtFNH/QQ+Y/RgxdU+8+8/muo4jo/jKnHssSezvjq6aPvYK+EAzAoRmXenAgUwHOjbiAXFqF8gScbbuLRlF0MsTKn/puIyFnvJd...",
"passwordHash":"d4de34f15aeadfb34bdf1fbbd57134b2baeb142c"
}
Risposta:
{
"id":"507f191e810c19729de860ea",
"lastUpdated":"2016-07-06T12:43:16.866Z"
}
La voce mongodb sarebbe simile a questa:
{
"id": "507f191e810c19729de860ea",
"passwordHash": "d4de34f15aeadfb34bdf1fbbd57134b2baeb142c",
"data": "DWCx6wR9ggPqPRrhU4O4oLN5P09onApoAULX4Xt+ckxswtFNH/QQ+Y/RgxdU+8+8/muo4jo/jKnHssSezvjq6aPvYK+EAzAoRmXenAgUwHOjbiAXFqF8gScbbuLRlF0MsTKn/puIyFnvJd...",
"lastUpdated": "2016-07-06T12:43:16.866Z"
}
Un utente può recuperare i propri dati con una richiesta GET a /api/data/{id}/{passwordHash}
, quindi per l'esempio sopra:
/api/data/507f191e810c19729de860ea/d4de34f15aeadfb34bdf1fbbd57134b2baeb142c
Risposta:
{
"data":"DWCx6wR9ggPqPRrhU4O4oLN5P09onApoAULX4Xt+ckxswtFNH/QQ+Y/RgxdU+8+8/muo4jo/jKnHssSezvjq6aPvYK+EAzAoRmXenAgUwHOjbiAXFqF8gScbbuLRlF0MsTKn/puIyFnvJd...",
"lastUpdated":"2016-07-06T12:43:16.866Z"
}
Poiché il valore id (ID oggetto MongoDB) non è eccessivamente complesso, un utente malintenzionato può potenzialmente indovinare qualcun altro id e recuperare i propri dati tramite l'API. Per questo motivo ho deciso di utilizzare l'id insieme all'hash della password dell'utente come chiave per rendere più difficile per l'utente malintenzionato indovinare la chiave univoca di qualcun altro. Tuttavia, se avessi usato solo l'ID oggetto come chiave e anche se potevano indovinare l'id di un altro utente, avrebbero recuperato solo i loro dati crittografati (non l'hash della password), che avrebbero quindi dovuto decodificare prima di leggere i dati. Questa sarebbe un'alternativa migliore per memorizzare l'hash della password? Ironia della sorte, questo sarebbe quindi rispondere al problema bcrypt come se non stavo memorizzando gli hash delle password sul server, non avrei bisogno di hash la password (utilizzata per crittografare i dati lato client) a tutti ...
Quindi, in conclusione, la domanda relativa alla mia app / api è molto più complessa della domanda, ma non posso davvero pensare a come inquadrarla correttamente (forse ho bisogno di cambiare la domanda ). Tuttavia, se qualcuno ha qualche opinione sugli aspetti di sicurezza del mio approccio dati i requisiti, sarei molto grato per l'input.