Bezpieczne liczby losowe w javascript?

Jak wygenerować kryptograficznie bezpieczne liczby losowe w javascript?

Author: Kyle, 2010-11-03

6 answers

Możesz na przykład używać ruchu myszy jako zalążka dla liczb losowych, odczytywać czas i pozycję myszy za każdym razem, gdy wystąpi zdarzenie onmousemove, podawać te dane do funkcji wybielania, a będziesz mieć pod ręką losową pierwszą klasę. Upewnij się jednak, że użytkownik przesunął mysz wystarczająco, zanim użyjesz danych.

Edit: sam trochę pobawiłem się z tą koncepcją tworząc generator haseł, nie gwarantowałbym, że moja funkcja wybielania jest bezbłędna, ale będąc stale reseded jestem prawie pewien, że to wystarczy do pracy: ebusiness.hopto.org/generator.htm

Edit2: teraz działa ze smartfonami, ale tylko przez wyłączenie funkcji dotykowej, gdy Entropia jest zebrana. Android nie będzie działał poprawnie w żaden inny sposób.

 22
Author: aaaaaaaaaaaa,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-03-17 01:01:17

Była dyskusja w WHATWG na temat dodania tego do okna.obiekt kryptograficzny. Możesz przeczytać dyskusję i sprawdzić proponowane API i błąd webkit (22049).

Po prostu przetestowałem następujący kod w Chrome , aby uzyskać losowy bajt:

(function(){
  var buf = new Uint8Array(1);
  window.crypto.getRandomValues(buf);
  alert(buf[0]);
})();
 55
Author: Paul V,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-12-30 16:50:50

W kolejności, myślę, że Twoje najlepsze zakłady to:

  1. okno.krypto.getRandomValues lub window.msCrypto.getRandomValues
  2. funkcja randomWords biblioteki sjcl ( http://crypto.stanford.edu/sjcl/)
  3. generator liczb losowych biblioteki Isaaca (który jest zasiewany przez matematykę.losowe, więc nie do końca bezpieczne kryptograficznie) (https://github.com/rubycon/isaac.js )

Okno.krypto.getRandomValues jest zaimplementowany w Chrome już od jakiegoś czasu, a stosunkowo niedawno również w Firefoksie. Niestety, Internet Explorer 10 i wcześniej nie implementują tej funkcji. IE 11 ma okno.msCrypto, który realizuje to samo. sjcl ma wielki generator liczb losowych zasiany z ruchów myszy, ale zawsze jest szansa, że albo mysz nie przesunęła się wystarczająco, aby zasiać generator, lub że użytkownik jest na urządzeniu mobilnym, gdzie nie ma ruchu myszy w ogóle. Dlatego polecam mieć przypadek awaryjny, w którym można jeszcze uzyskaj niezabezpieczony Numer losowy, jeśli nie ma wyboru. Oto jak sobie z tym poradziłem:

function GetRandomWords (wordCount) {
    var randomWords;

    // First we're going to try to use a built-in CSPRNG
    if (window.crypto && window.crypto.getRandomValues) {
        randomWords = new Int32Array(wordCount);
        window.crypto.getRandomValues(randomWords);
    }
    // Because of course IE calls it msCrypto instead of being standard
    else if (window.msCrypto && window.msCrypto.getRandomValues) {
        randomWords = new Int32Array(wordCount);
        window.msCrypto.getRandomValues(randomWords);
    }
    // So, no built-in functionality - bummer. If the user has wiggled the mouse enough,
    // sjcl might help us out here
    else if (sjcl.random.isReady()) {
        randomWords = sjcl.random.randomWords(wordCount);
    }
    // Last resort - we'll use isaac.js to get a random number. It's seeded from Math.random(),
    // so this isn't ideal, but it'll still greatly increase the space of guesses a hacker would
    // have to make to crack the password.
    else {
        randomWords = [];
        for (var i = 0; i < wordCount; i++) {
            randomWords.push(isaac.rand());
        }
    }

    return randomWords;
};
Musisz dołączyć sjcl.js i isaac.js dla tej implementacji i pamiętaj, aby uruchomić kolektor entropii sjcl zaraz po załadowaniu strony:
sjcl.random.startCollectors();

Sjcl jest na dwóch licencjach BSD i GPL, podczas gdy isaac.js to MIT, więc jest całkowicie bezpieczny w użyciu w każdym projekcie. Jak wspomniano w innej odpowiedzi, clipperz jest inną opcją, jednak z jakiegokolwiek dziwacznego powodu, jest na licencji AGPL. Nie widziałem jeszcze nikogo, kto zdaje się rozumieć, jakie konsekwencje ma to dla biblioteki JavaScript, ale ogólnie bym tego unikał.

Jednym ze sposobów na poprawienie kodu, który opublikowałem, może być Przechowywanie stanu generatora liczb losowych Isaaca w localStorage, więc nie jest on ponownie wysyłany za każdym razem, gdy strona jest ładowana. Isaac wygeneruje losową sekwencję, ale dla celów kryptograficznych, zalążek jest najważniejszy. Siew z matematyką.losowe jest złe, ale przynajmniej trochę mniej źle, jeśli nie jest to koniecznie przy każdym ładowaniu strony.

 27
Author: ZeroG,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-01-26 20:59:08

Użycie window.crypto.getRandomValues, Tak:

var random_num = new Uint8Array(2048 / 8); // 2048 = number length in bits
window.crypto.getRandomValues(random_num);

Jest to obsługiwane we wszystkich nowoczesnych przeglądarkach i wykorzystuje generator losowy systemu operacyjnego (np. /dev/urandom). Jeśli potrzebujesz zgodności z IE11, musisz użyć ich poprzedzonej implementacji poprzez var crypto = window.crypto || window.msCrypto; crypto.getRandomValues(..).

Zauważ, że API window.crypto może również generować klucze wprost , co może być lepszą opcją.

 10
Author: phihag,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-09-29 06:43:10

Możesz spróbować http://sourceforge.net/projects/clipperzlib/ Posiada implementację Fortuna , która jest kryptograficznie bezpiecznym generatorem liczb losowych. (Spójrz na src/js/Clipperz/Crypto/PRNG.js). Wydaje się, że używa myszki jako źródła losowości, jak również.

 4
Author: ameer,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-11-03 00:27:17

Po pierwsze, potrzebujesz źródła entropii. Na przykład ruch myszy, hasło lub inne. Ale wszystkie te źródła są bardzo dalekie od losowych i gwarantują 20 bitów entropii, rzadko więcej. Następnym krokiem, który musisz wykonać, jest użycie mechanizmu takiego jak "KDF oparty na hasłach", który sprawi, że obliczeniowo trudno będzie odróżnić dane od losowych.

 1
Author: user2674414,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-08-02 10:20:52