¿Esta función hash es segura?

0

A continuación se muestra la implementación de la función hash de la biblioteca roguewave. Devuelve un hash de 32 bits. La operación principal es A = B ^ ((C < < 5) | (C > > 27)). ¿Es seguro usar este hash como verificación de contraseña o es posible recuperar todas las B usadas invirtiéndolas?

const unsigned RW_HASH_SHIFT = 5;

inline static void mash(unsigned& hash, unsigned chars)
{
  hash = (chars ^
       ((hash << RW_HASH_SHIFT) |
        (hash >> (RWBITSPERBYTE*sizeof(unsigned) - RW_HASH_SHIFT))));
}

unsigned
RWCStringRef::hash() const
{
  unsigned hv       = (unsigned)length(); // Mix in the string length.
  unsigned i        = length()*sizeof(char)/sizeof(unsigned);
  const unsigned* p = (const unsigned*)data();
  {
    while (i--)
      mash(hv, *p++);           // XOR in the characters.
  }
  // XOR in any remaining characters:
  if ((i = length()*sizeof(char)%sizeof(unsigned)) != 0) {
    unsigned h = 0;
    const char* c = (const char*)p;
    while (i--) 
      h = ((h << RWBITSPERBYTE*sizeof(char)) | *c++);
    mash(hv, h);
  }
  return hv;
}
    
pregunta Jasper 22.08.2014 - 14:09
fuente

2 respuestas

10

Esto es extremadamente inseguro, hasta el punto de ser inútil:

  1. Su función hash no es una función unidireccional. Uno puede instantáneamente (con tiempo de ejecución constante y bajo) calcular una entrada que produzca un hash dado si permite contraseñas de 4 caracteres arbitrarios como entradas deshaciendo el XOR con el valor de hash inicial formado a partir de la longitud de la contraseña. Con un poco de ingenio, es probable que dicha preimagen se pueda generar de manera muy efectiva incluso si el conjunto de caracteres de entrada está restringido.

  2. Incluso si su función hash fuera una función unidireccional criptográficamente sólida, no sería una buena función de hashing de contraseñas porque es rápida. Lo ideal es que desee una función derivada clave que, como PBKDF2 o scrypt, tenga un factor de trabajo configurable que le permita ajustar el nivel de dificultad de su atacante (y la carga de trabajo de su servidor) a nuevas condiciones con el tiempo.

  3. Tu hash está tan lejos en el lado corto que es difícil llamarlo seguro, incluso si todo lo demás estaba bien. Como señaló Andrey en una respuesta anterior, cualquier hash de 32 bits se puede adivinar en (tip.) 0.5 * 2 ^ 32 intentos. Para no ser un cuello de botella de seguridad, este número siempre debe ser mayor que el necesario para adivinar la contraseña. Sin embargo, 32 bits de entropía son tan bajos que un número similar (28 bits) sirve para ilustrar una contraseña débil en la famosa caricatura de contraseña de xkcd .

respondido por el pyramids 22.08.2014 - 16:24
fuente
8

La función hash de 32 bits no puede ser segura para la verificación de la contraseña.

El problema aquí es que es "fácil" encontrar una contraseña en conflicto, es decir, una contraseña, que contiene el valor hash "correcto" a pesar de ser diferente de la contraseña original. En promedio, se necesitarán 2 ^ 31 intentos de contraseña para obtener dicha colisión, que se considera muy débil según el estándar actual.

    
respondido por el Andrey 22.08.2014 - 15:15
fuente

Lea otras preguntas en las etiquetas