-
-
Notifications
You must be signed in to change notification settings - Fork 276
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
fallback random number generators considered insecure #16
Comments
See: https://github.com/dcodeIO/bcrypt.js/tree/master/dist The default build comes without ISAAC. Using it is optional. |
Sounds good! It looks like ISAAC is built around Math.random [1] which is not considered a CSPRNG [2]. Maybe you can tell me anything about the security assurances ISAAC provides and if it's comparable to a native Web Crypto API implementation? The API of setRandomFallback and the text on https://github.com/dcodeIO/bcrypt.js/tree/master/dist do not state anything about any possible differences in security when using a fallback like ISAAC. I'm a bit worried that a reader might not realize that choosing a custom fallback instead of using the native solution might negatively impact the security of the generated hashes. [1] https://github.com/rubycon/isaac.js/blob/master/isaac.js#L103 |
More information on ISAAC is available at:
|
Nice warning in the docs. Following that crypto.stackexchange.com link it states: "The major issue is on the way which it is initially seeded.". Seeing that ISAAC is initially seeded with the cryptographically insecure Math.random my worries are not completely taken away. Same for the reddit link: Another source suggest that it's important that the seed should have enough entropy. When reading about Math.random in different browsers it looks like this is not the function that can provide that kind of strong entropy. But, since I'm not authoritative on this subject it's all a bit of speculation on my side. |
Though fpirsch/twin-bcrypt#2 (comment) seems to underwrite the importance of good entropy, even when seeding ISAAC. |
I've added a basic entropy accumulator that uses some common sources of randomness to seed ISAAC, like mouse and touch movements, timestamps, Math.random and a bit of timing information. See: https://github.com/dcodeIO/bcrypt.js/blob/master/src/bcrypt/prng/accum.js This should already be a lot better than using Math.random alone, but it's surely still far from what's possible. I have also added a note to the distributions page referencing the accumulator in the hope that it can serve as a good starting point for everyone interested in improving it. Some open questions besides "Is this implementation sane?" are:
Please let me know of possible improvements or, even better, send me pull requests. Edit: It looks to me like providing ISAAC bundled with bcrypt.js is terrible. There should probably be another independent library providing a) a stream cipher accumulating suitable entropy sources and b) ISAAC or a similar CSPRNG seeded from it. |
I like the decision to take out any fallback PRNG and warn that if the user supplies it's own that it should by a Cryptographically Secure PRNG. I still have doubts about actively providing Personally, I would go a step further and take out |
If Web Crypto API is available, whatever is specified with setRandomFallback is not used at all.
In case of doubt and for what it's worth I'd prefer to keep it considering exotic environments that are neither a real browser nor node.js. Something like SharpJS for example, or even Cordova (e.g. on older Android), where supplying a function returning a plain array instead of taking a typed array to populate is easier to do. |
"If Web Crypto API is available, whatever is specified with setRandomFallback is not used at all." That's good to know! Tnx for clarifying. |
Can I suggest you document this point? I only spotted it after digging around in the code and finding the link to this issue. [Edit: just to be clear, it does say that the WebCrypto API may be used if available, but not that it will always be used if available, even if you set the fallback] |
I've read a lot of things since the LibreSSL fork about not using a userland CSPRNG, simply because secure randomness can only be assured by the kernel [1][2][3][4].
I'm wondering why these rules would not apply to JavaScript programs. I suspect that this library would be more secure if it by default hard fails if neither Web Crypto nor Nodejs crypto are available, instead of falling back to the "userland" ISAACs PRNG.
[1] http://sockpuppet.org/blog/2014/02/25/safely-generate-random-numbers/
[2] https://news.ycombinator.com/item?id=8034710
[3] http://news.sixgun.org/2014/07/21/linux-kernel-libressl/
[4] http://lwn.net/Articles/606141/
The text was updated successfully, but these errors were encountered: