Sto cercando una soluzione affidabile per confrontare due stringhe senza perdere il loro contenuto attraverso le differenze di tempo. La lunghezza delle stringhe è non secret.
Lo sfondo è questo: sto implementando l'autenticazione basata su password per un'applicazione web. Le password vengono sottoposte a hash con bcrypt e archiviate in un database. Piuttosto che dare all'applicazione l'accesso diretto agli hash in modo che controlli la password, vorrei delegare questo al sistema di database stesso. L'applicazione esegue solo l'hash della password e quindi passa l'hash a una procedura di database. Questa procedura ha privilegi speciali per accedere agli hash memorizzati e confrontarli con l'hash fornito. L'obiettivo è proteggere gli hash dagli attacchi SQL injection. Un'idea simile è descritta in questa presentazione .
Ovviamente, questo schema è efficace solo se la procedura non perde alcuna informazione sugli hash memorizzati. Quindi il confronto delle stringhe deve essere temporizzato.
Sono a conoscenza del seguente metodo (pseudo-codice):
string_comp(str_1, str_2): if str_1.length != str_2.length: return false else: result := 0 for i := 0 to str_1.length - 1: result := result | (str_1[i] ^ str_2[i]) return result == 0
Tuttavia, questo è piuttosto ingombrante e non sono sicuro che funzioni come previsto in linguaggi di alto livello come SQL.
Un altro suggerimento comune è quello di cancellare le stringhe e quindi confrontare il hash . Questo sarebbe molto più semplice del codice sopra.
Quale metodo è preferibile? Se dovessi usare la soluzione hash, quale algoritmo sceglierei per non degradare la forza di bcrypt (nemmeno teoricamente)? SHA-256? SHA-384? SHA-512?