La funzione JavaScript Math.random()
è progettata per restituisce un singolo valore in virgola mobile n tale che 0 ≤ n < 1. È (o almeno dovrebbe essere) ampiamente noto che l'output è non crittograficamente sicuro. Le implementazioni più moderne utilizzano l'algoritmo XorShift128 + che può essere facilmente rotto . Poiché non è affatto raro che le persone di utilizzino erroneamente quando hanno bisogno di meglio casualità, perché i browser non lo sostituiscono con un CSPRNG? So che Opera lo fa *, almeno. L'unico ragionamento che potrei pensare sarebbe che XorShift128 + sia più veloce di un CSPRNG, ma su computer moderni (e anche non così moderni), sarebbe banale produrre centinaia di megabyte al secondo usando ChaCha8 o AES-CTR. Questi sono spesso abbastanza veloci che un'implementazione ben ottimizzata può essere strozzata solo dalla velocità di memoria del sistema. Anche un'implementazione non ottimizzata di ChaCha20 è estremamente veloce su tutte le architetture e ChaCha8 è più che due volte più veloce.
Capisco che non possa essere ridefinito come CSPRNG poiché lo standard non fornisce esplicitamente alcuna garanzia di idoneità per l'uso crittografico, ma sembra che non vi sia alcun svantaggio per i venditori di browser che lo fanno volontariamente. Ridurrebbe l'impatto dei bug in un gran numero di applicazioni Web senza violare lo standard (richiede solo che l'output sia round-to-close-even IEEE 754 numeri), prestazioni decrescenti o violazione della compatibilità con le applicazioni Web.
MODIFICA: alcune persone hanno sottolineato che questo potrebbe potenzialmente indurre le persone ad abusare di questa funzione, anche se lo standard dice che non si può fare affidamento su di esso per la sicurezza crittografica. Nella mia mente, ci sono due fattori opposti che determinano se utilizzare o meno un CSPRNG sarebbe un vantaggio di sicurezza netto:
-
Falso senso di sicurezza : il numero di persone che altrimenti utilizzerebbero una funzione progettata per questo scopo, come
window.crypto
, decidi invece di utilizzareMath.random()
perché è crittograficamente sicuro sulla piattaforma di destinazione prevista. -
Sicurezza opportunistica : il numero di persone che non conoscono meglio e utilizzano comunque
Math.random()
per le applicazioni sensibili che potrebbero essere protette dal proprio errore. Ovviamente, sarebbe meglio educarli, ma questo non è sempre possibile.
Sembra sicuro assumere che il numero di persone che sarebbero protette dai propri errori supererebbe di molto il numero di persone che sono cullate in un falso senso di sicurezza.
* Come indicato da CodesInChaos, questo non è più vero ora che Opera è basato su Chromium.
Diversi importanti browser hanno riportato segnalazioni di bug che suggeriscono di sostituire questa funzione con un'alternativa crittograficamente sicura, ma nessuna delle modifiche sicure suggerite è atterrato:
Gli argomenti per corrispondono sostanzialmente alla mia. Gli argomenti contro di essa variano da prestazioni ridotte su microbenchmark (con scarso impatto nel mondo reale) a equivoci e miti, come l'idea errata che un CSPRNG si indebolisca nel tempo quando viene generata più casualità. Alla fine, Chromium ha creato un oggetto crittografico completamente nuovo e Firefox ha sostituito il proprio RNG con l'algoritmo XorShift128 +. La funzione Math.random()
rimane completamente prevedibile.