hash short integer per mitigare gli attacchi temporali sulle password

1

Supponendo di voler proteggere contro timing attacchi alle nostre password con hash perché anche per sapere che l'hash può dare all'attaccante un vantaggio significativo , quindi potremmo voler eseguire un confronto di stringhe a tempo costante o fisso per i nostri hash.

Tuttavia il confronto a tempo costante non è un compito semplice come ci si potrebbe aspettare perché il compilatore potrebbe essere contro noi e ritardi casuali semplici saranno solo ferma l'attaccante più ingenuo .

Con tutte queste premesse possiamo mitigare questo problema (è necessario? le password sono spesso memorizzate in database / supporti durevoli e in qualsiasi sistema reale questo aggiungerà rumore ) usando questa pseudo- codice:

// Possibly pre-computed or cached values...
string passwordHash = "550b1f8802ca3d7a987fc46a2af408c3";
int shortPasswordHash = SimpleHash(passwordHash);

// Function to validate a password
bool IsPasswordValid(string hashedPasswordToValidate)
{
    if (SimpleHash(hashedPasswordToValidate) != shortPasswordHash)
        return false;

    return hashedPasswordToValidate.Equals(hashedPassword);
}

Si noti che il confronto tra stringhe (su password hash) è ancora vulnerabile a un attacco di temporizzazione, ma le probabilità di perdita di informazioni utili a un utente malintenzionato dovrebbero essere inferiori (e questo algoritmo è facilmente applicabile nella maggior parte delle lingue, anche senza una costante incorporata -time password / hash comparison).

Lo stesso ragionamento è applicabile anche se non abbiamo una password con hash ma direttamente testo in chiaro (!!!) come questo:

string password = "12345";
string longPasswordHash = BCrypt(password);
int shortPasswordHash = SumAllCharactersWithoutOverflow(longPasswordHash);

bool IsPasswordValid(string passwordToValidate)
{
    string longHash = BCrypt(passwordToValidate);
    int shortHash = SumAllCharactersWithoutOverflow(longHash);

    if (shortHash != shortPasswordHash)
        return false;

    return longHash.Equals(longPasswordHash);
}

Vogliamo / dobbiamo ancora utilizzare una funzione di confronto a tempo costante migliore in qualsiasi scenario non accademico del mondo reale?

    
posta Adriano Repetti 30.06.2016 - 14:24
fonte

1 risposta

1

In realtà si desidera garantire che la funzione di confronto abbia lo stesso intervallo di tempo indipendentemente dal successo o dal fallimento del confronto. Funzioni come strcmp () ecc. Possono scorciatoire e restituire un errore sul primo byte che non corrisponde.

Allo stesso modo con linguaggi di livello superiore con oggetti stringa, dove è possibile utilizzare == e! =, ci basiamo sull'implementazione dei compilatori.

Quindi, per garantire un tempo costante, una buona soluzione è eseguire sempre un confronto byte per byte di tutti i byte del valore hash e quindi restituire vero / falso in base a tale confronto.

ad esempio:

int contstant_time_compare(char *a, char *b)
{
    int i = 0;
    int len = strlen(a);
    int diff = 0;
    for(i = i ; i < len ; i++)
    {
         diff |=  a[i] ^ b[i]; 
    }
    return (0 == diff);
} 
    
risposta data 30.06.2016 - 14:42
fonte

Leggi altre domande sui tag