Estoy buscando una solución confiable para comparar dos cadenas sin perder su contenido a través de las diferencias de tiempo. La longitud de las cadenas es no secreta.
El fondo es el siguiente: estoy implementando autenticación basada en contraseña para una aplicación web. Las contraseñas se procesan con bcrypt y se almacenan en una base de datos. En lugar de dar a la aplicación acceso directo a los hashes para que compruebe la contraseña, me gustaría delegar esto en el sistema de base de datos. La aplicación solo utiliza la contraseña y luego pasa el hash a un procedimiento de base de datos. Este procedimiento tiene privilegios especiales para acceder a los hash almacenados y compararlos con el hash proporcionado. El objetivo es proteger los hashes contra los ataques de inyección de SQL. Una idea similar se describe en esta presentación .
Obviamente, este esquema solo es efectivo si el procedimiento no filtra información sobre los hashes almacenados. Por lo tanto, la comparación de cadenas debe ser segura en el tiempo.
Soy consciente del siguiente método (pseudocódigo):
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
Sin embargo, esto es bastante engorroso, y no estoy seguro de si funciona como se espera en lenguajes de alto nivel como SQL.
Otra sugerencia común es hash las cadenas y luego comparar las hashes . Esto sería mucho más simple que el código anterior.
¿Qué método es preferible? Si utilizara la solución hash, ¿qué algoritmo elegiría para no degradar la fuerza de bcrypt (ni siquiera en teoría)? SHA-256? SHA-384? SHA-512?