Quanto è sicuro questo generatore di password JavaScript?

3

Mi chiedo quanto è sicuro questo generatore di password JavaScript:

var Password = {

  _pattern : /[a-zA-Z0-9_\-\+\.\!\@\#\$\%\^\&\*\(\)\_\+\{\}\:\"\<\>\?\|\[\]\;\'\,\.\/\'\~\']/,

  _getRandomByte : function()
  {

    if(window.crypto && window.crypto.getRandomValues) 
    {
      var result = new Uint8Array(1);
      window.crypto.getRandomValues(result);
      return result[0];
    }
    else if(window.msCrypto && window.msCrypto.getRandomValues) 
    {
      var result = new Uint8Array(1);
      window.msCrypto.getRandomValues(result);
      return result[0];
    }
    else
    {
      return Math.floor(Math.random() * 256);
    }
  },

  generate : function(length)
  {
    return Array.apply(null, {'length': length})
      .map(function()
      {
        var result;
        while(true) 
        {
          result = String.fromCharCode(this._getRandomByte());
          if(this._pattern.test(result))
          {
            return result;
          }
        }        
      }, this)
      .join('');  
  }    

};

Inoltre, se qualcuno ha suggerito di renderlo migliore o più sicuro, sei il benvenuto.

Un'altra cosa, la lunghezza della password generata è fissata a value="16" , forse questa può essere una cattiva idea e non sarebbe meglio generare password con una lunghezza casuale, ad es. tra 12 - 16, o qualcos'altro.

    
posta user134969 24.01.2017 - 16:54
fonte

3 risposte

2

Il tuo problema è Math.random() . Quello non è crittograficamente sicuro. Penso che sia stato seminato in modo sicuro nella maggior parte delle implementazioni, quindi, se stai solo generando una password, stai bene. Ma se lo usi per generare un sacco di password diventeranno prevedibili. Non va bene. Ma è un po 'difficile da aggirare in JavaScript - se non hai un CSPRNG, non hai un CSPRNG ...

Potrebbero esserci anche altri problemi che mi sono sfuggiti, ma questo è ciò che spicca per me.

Per quanto riguarda la lunghezza della password, ci sono meno password di lunghezza compresa tra 1 e 15 caratteri rispetto alle password lunghe 16 caratteri, quindi non ti manca molto. Se vuoi comunque una lunghezza a caso, devi pensare a quale distribuzione tragga la lunghezza. L'utilizzo di una distribuzione uniforme (ad esempio il tuo _getRandomByte ) ti darà meno entropia e non più, dal momento che è probabile che generi password brevi.

    
risposta data 24.01.2017 - 18:19
fonte
1

Il principio generale è valido: genera una password selezionando length caratteri a caso. I dettagli sono dove si trovano i problemi:

  1. Tu devi utilizzare un generatore di numeri casuali protetto da crittografia. Math.random() non è così, e per questo mai deve essere usato
  2. Il modo in cui stai filtrando le scelte casuali è corretto (tutti i personaggi sono selezionati con uguale probabilità) ma inefficienti; hai un ciclo in cui disegni un byte casuale (256 valori possibili) e lo butti via se non è uno dei tuoi caratteri consentiti, ripetendo finché non ne scegli uno adatto. Il set di caratteri consentiti è di circa 95, il che significa che la maggior parte delle volte si ottiene un "miss". Se per prima cosa prendi il resto della divisione del byte casuale tra 128 ottieni anche risultati corretti e migliorerai sensibilmente il "tasso di successo". (Questo è un trucco standard di generazione di numeri casuali: dovresti usare una libreria che fa già questo per te!)
  3. Devi pensare chiaramente al target di sicurezza e quindi alla lunghezza minima consentita della password. Se le tue password sono disegnate da 95 caratteri distinti, ogni carattere contribuisce circa log2(95) = 6.6 bit di entropia. Hai bisogno di 10 caratteri per arrivare a 64 bit di entropia, che penso sia il minimo indispensabile che nessuno dovrebbe mai usare (accessi al sito Web per siti in cui non si rompe la banca se qualcuno ha violato la password, e tu potresti voglio memorizzare le password). 12 caratteri ti portano a 79 bit, il che credo sia un buon bilanciamento tra lunghezza e sicurezza.
risposta data 24.01.2017 - 23:01
fonte
0

Devi convalidare il parametro length . Se chiami Password.generate() , potresti aspettarti che venga generata una password, ma in realtà restituisce una stringa vuota.

    
risposta data 24.01.2017 - 20:49
fonte

Leggi altre domande sui tag