Funkcja JavaScript Math.random ()
służy do zwracania pojedynczej wartości zmiennoprzecinkowej IEEE n takiej, że 0 ≤ n < 1. Powszechnie wiadomo (lub przynajmniej powinno być), że dane wyjściowe nie są kryptograficznie bezpieczne. Większość nowoczesnych implementacji wykorzystuje algorytm XorShift128 +, który można łatwo złamać. Ponieważ często zdarza się, że ludzie omyłkowo go używają, gdy potrzebują lepszej losowości, dlaczego przeglądarki nie zastępują jej CSPRNG? Wiem, że przynajmniej Opera to robi *. Jedynym rozumowaniem, jakie mógłbym wymyślić, byłoby to, że XorShift128 + jest szybszy niż CSPRNG, ale na nowoczesnych (i nawet nie tak nowoczesnych) komputerach byłoby trywialne wytwarzanie setek megabajtów na sekundę przy użyciu ChaCha8 lub AES-CTR. Są one często na tyle szybkie, że dobrze zoptymalizowana implementacja może zostać zablokowana jedynie przez szybkość pamięci systemu. Nawet niezoptymalizowana implementacja ChaCha20 jest niezwykle szybka na wszystkich architekturach, a ChaCha8 jest ponad dwa razy szybsza.
Rozumiem, że nie można go ponownie zdefiniować jako CSPRNG, ponieważ standard wyraźnie nie daje gwarancji nadaje się do użytku kryptograficznego, ale wydaje się, że nie ma żadnych wad, aby dostawcy przeglądarek robili to dobrowolnie. Zmniejszyłoby to wpływ błędów w dużej liczbie aplikacji internetowych bez naruszania standardu (wymaga tylko, aby dane wyjściowe były zaokrąglone do najbliższej parzystej wartości IEEE 754), zmniejszając wydajność lub łamiąc kompatybilność z aplikacjami internetowymi.
EDYCJA: Kilka osób zwróciło uwagę, że może to potencjalnie spowodować nadużywanie tej funkcji, nawet jeśli standard mówi, że nie można na niej polegać w zakresie bezpieczeństwa kryptograficznego. Moim zdaniem istnieją dwa przeciwstawne czynniki, które decydują o tym, czy użycie CSPRNG przyniesie korzyści w zakresie bezpieczeństwa netto:
Fałszywe poczucie bezpieczeństwa - liczba osób, które w innym przypadku używałyby funkcji przeznaczonej do tego celu, takiej jak
window.crypto
zdecyduj się zamiast tego na użycieMath.random ()
, ponieważ jest on kryptograficznie bezpieczny na zamierzonej platformie docelowej.-
Oportunistyczny bezpieczeństwo - liczba osób, które nie znają się lepiej i mimo wszystko używają
Math.random ()
dla wrażliwych aplikacji, które byłyby chronione przed własnym błędem. Oczywiście zamiast tego lepiej byłoby ich uczyć, ale nie zawsze jest to możliwe.
Można bezpiecznie założyć, że liczba osób, które byłyby chronione przed własną błędy znacznie przekroczyłyby liczbę osób, które są uśpione w fałszywym poczuciu bezpieczeństwa.
* Jak wskazuje CodesInChaos, nie jest to już prawdą teraz, gdy Opera jest oparta na Chromium. sub>
W kilku głównych przeglądarkach pojawiły się raporty o błędach sugerujące zastąpienie tej funkcji alternatywą bezpieczną kryptograficznie, ale żadna z sugerowanych bezpiecznych zmian nie wylądowała:
-
Wątek Chromium: https://bugs.chromium.org/p/chromium/issues/detail?id=45580
-
Wątek Firefox : https://bugzilla.mozilla.org/show_bug.cgi?id=322529
Argumenty dla zmiana zasadniczo pasuje do mojej. Argumenty przeciwko temu są różne, od obniżonej wydajności mikroznaków (z niewielkim wpływem w świecie rzeczywistym) po nieporozumienia i mity, takie jak błędne wyobrażenie, że CSPRNG słabnie z czasem, gdy generowana jest większa losowość. Ostatecznie Chromium stworzył całkowicie nowy obiekt kryptograficzny, a Firefox zastąpił swój RNG algorytmem XorShift128 +. Funkcja Math.random ()
pozostaje w pełni przewidywalna.