Hashes cortos de enteros para mitigar los ataques de tiempo en las contraseñas

1

Suponiendo que queremos proteger contra tiempo ataques a nuestras contraseñas con hash porque incluso para saber el hash puede dar al atacante una ventaja significativa entonces es posible que queramos realizar una comparación de cadena de tiempo constante o tiempo fijo para nuestros hash.

Sin embargo, la comparación de tiempo constante no es una tarea sencilla como podemos esperar porque el compilador puede ser contra us y los retrasos aleatorios simples serán justos Detén al atacante más ingenuo .

Con todas estas premisas podemos mitigar este problema (¿es necesario? Las contraseñas a menudo se almacenan en bases de datos / medios duraderos y en cualquier sistema del mundo real esto agregará noise ) usando este pseudo código:

// 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);
}

Tenga en cuenta que la comparación de cadenas (en la contraseña con hash) aún es vulnerable a un ataque de tiempo, pero las posibilidades de filtrar información útil a un atacante deberían ser menores (y este algoritmo es fácilmente aplicable en la mayoría de los idiomas, incluso en aquellos sin una constante integrada -la comparación de contraseñas / hash).

El mismo razonamiento también es aplicable si no tenemos una contraseña con hash pero directamente en texto sin formato (!!!) como este:

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);
}

¿Todavía queremos / necesitamos usar una mejor función de comparación de tiempo constante en cualquier escenario no académico del mundo real?

    
pregunta Adriano Repetti 30.06.2016 - 14:24
fuente

1 respuesta

1

Realmente desea asegurarse de que la función de comparación tome la misma cantidad de tiempo independientemente del éxito o el fracaso de la comparación. Las funciones como strcmp (), etc. pueden hacer un atajo y devolver un error en el primer byte que no coincide.

Del mismo modo, con lenguajes de nivel superior con objetos de cadena, donde se pueden usar == y! =, dependemos de la implementación de los compiladores.

Por lo tanto, para garantizar un tiempo constante, una buena solución es realizar siempre una comparación byte a byte de todos los bytes del valor hash, y luego devolver verdadero / falso según esa comparación.

por ejemplo:

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);
} 
    
respondido por el Colin Cassidy 30.06.2016 - 14:42
fuente

Lea otras preguntas en las etiquetas