Questa funzione di hash è sicura?

0

Di seguito è riportata l'implementazione della funzione hash della libreria roguewave. Restituisce un hash a 32 bit. L'operazione di base è A = B ^ ((C < < 5) | (C > > 27)). Questo hash è sicuro da usare come controllo della password o è possibile recuperare tutti i B usati invertendoli?

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;
}
    
posta Jasper 22.08.2014 - 14:09
fonte

2 risposte

10

Questo è estremamente pericoloso, al punto di essere inutile:

  1. La tua funzione di hash non è una funzione a senso unico. Uno può istantaneamente (con runtime costante e basso) calcolare un input che produce un determinato hash se si consente l'inserimento di password arbitrarie di 4 caratteri come input annullando lo XOR con il valore hash iniziale formato dalla lunghezza della password. Con un po 'di ingenuità, è probabile che tale preimage possa essere generato in modo molto efficace anche se il set di caratteri di input è limitato.

  2. Anche se la tua funzione di hash era una funzione unidirezionale crittograficamente strong, non sarebbe una buona funzione di hashing della password perché è veloce. Idealmente, si desidera una funzione derivativa chiave che, come PBKDF2 o scrypt, abbia un fattore di lavoro configurabile che consente di regolare il livello di difficoltà per l'utente malintenzionato (e il carico di lavoro del server) a nuove condizioni nel tempo.

  3. Il tuo hash è così lontano che è difficile definirlo sicuro anche se tutto il resto andava bene. Come ha sottolineato Andrey in una risposta precedente, qualsiasi hash a 32 bit può essere indovinato in (typ.) 0.5 * 2 ^ 32 tentativi. Per non essere un collo di bottiglia per la sicurezza, questo numero dovrebbe sempre essere maggiore di quello che sarebbe necessario per indovinare la password. Tuttavia, 32 bit di entropia sono così bassi che un numero simile (28 bit) funziona per illustrare una password debole nel famoso fumetto di password xkcd .

risposta data 22.08.2014 - 16:24
fonte
8

La funzione hash a 32 bit non può essere sicura ai fini della verifica della password.

Il problema è che è "facile" trovare una password colliding, ovvero una password, che esegue il hash del valore "corretto" nonostante sia diversa dalla password originale. In media ci vorranno 2 ^ 31 prove di password per ottenere tale collisione, che è considerata molto debole per lo standard di oggi.

    
risposta data 22.08.2014 - 15:15
fonte

Leggi altre domande sui tag