Obiettivo: disporre dell'autenticazione basata su token / cookie che non richiede il mantenimento delle sessioni sul server
TL; DR: qual è il meccanismo accettato per aggirare la limitazione di 72 caratteri di BCrypt?
Versione lunga:
Dopo aver letto questa risposta ho tentato di implementare l'autenticazione su un server basato su REST usando BCrypt come algoritmo di hashing e un Rotante segreto lato server. L'idea di base era che, una volta completata l'autenticazione con un nome utente e una password, il server avrebbe impostato un cookie contenente un hash basato sulla concatenazione di quanto segue:
- Il segreto lato server
- L'ID utente e i gruppi a cui appartiene l'utente
- L'ora in cui il token è stato distribuito
Questo verrà quindi sottoposto a hash con un salt, e il risultato andrebbe nel cookie, per essere letto e verificato dal server (possibile perché l'ID utente, i gruppi e la data vengono trasmessi in chiaro dal client, e il segreto lato server è in memoria, con il segreto che serve come garanzia che il client non ha fatto tutti gli altri valori su se stessi).
Tutto questo ha funzionato bene fino a quando ho realizzato che BCrypt ha un limite di 72 caratteri sul testo in chiaro hash (qualsiasi cosa dopo che questi 72 caratteri non influenzano l'hash dell'output).
Questo è un problema perché i dati di cui sopra ammontavano a più di 72 caratteri e consentendo a tempo, ID utente, gruppi o chiave segreta di essere "ultimi" nell'input e non influenzare l'output, aprono buchi nella sicurezza del sistema (I vecchi token sono infinitamente validi, oppure le persone possono modificare arbitrariamente il loro ID utente / ruolo).
Ironia della sorte, quando finalmente ho capito perché il mio sistema produceva identici hash basati su input diversi e cercati su google, sembra questo tipo di situazione era previsto da alcuni .
In ogni caso, la domanda: Qual è il meccanismo accettato per aggirare la limitazione di 72 caratteri di BCrypt?
Alcuni pensieri preventivi: la creazione delle tue variazioni sugli algoritmi crittografici standard è qualcosa di cui sono stato avvisato per tutto il tempo che posso ricordare, quindi non sono sicuro al 100% quale sarebbe la migliore linea d'azione.
Le opzioni ovvi includono:
- suddivisione in blocchi dell'ingresso e applicazione di BCrypt a turno a turno e / o in cascata;
- utilizzando un altro hash (non crittografico?) sull'input per ridurne le dimensioni
- usando la compressione semplice (ma potrebbe essere inefficace con un pezzetto di testo in chiaro)
- passaggio a un altro algoritmo (SHA-3 è stato recentemente finalizzato, per esempio).
(potrebbero esserci altre cose sbagliate con l'idea di cui sopra, nel qual caso sarei naturalmente felice di essere corretto!)