simbo1905 / thinbus-srp-npm

This package provides a Javascript Secure Remote Password SRP SRP6a implementation for web browsers to perform a zero-knowledge proof-of-password to a web server.
101 stars 14 forks source link

Uncaught ReferenceError: random16byteHex is not defined #8

Closed simplenotezy closed 6 years ago

simplenotezy commented 6 years ago

Tried pulling in this library, and grabbing the Login and Register from your demo code. However, when typing in e-mail field it fails with the following error:

 Uncaught ReferenceError: random16byteHex is not defined

This is the line that's calling ranndom16byteHex.

    $(options.emailId).on('keyup', $.proxy(function (event) {
        // see recommendation in the thinbus docs to advance the random number generated in browsers that do not have secure randoms. 
        random16byteHex.advance(Math.floor(event.keyCode / 4));
    }, me));

It seems as though random16byteHex is not exported from browser.js and I guess it should be.

simbo1905 commented 6 years ago

Background

The full discussion about random numbers with this code is at https://bitbucket.org/simon_massey/thinbus-srp-js/src/cd27bbc355bc8f949c30a002266a58c45c82d1cc/PRNG.md?at=master&fileviewer=file-view-default

random16byteHex.random(); checks for window.crypto and uses it for random numbers and if not falls back to an Isaac generator.

random16byteHex.advance(x) will do nothing if the browser has window.crypto else will spin forward the Isaac generator. That is done as Isaac has less randomness initially.

Upon page load the isaac prng is spun forwards for 100ms. So that code is using the user typing their email address to spin forward the generator some more.

Workaround

One possible workaround to the bug is to polyfill window.crypto. Then you won't be attempting to use an Isaac generator that doesn't have that additional warm-up step. Yet looking at the popular polyfillers I don't think that they are suitable. For example, they seed with Math.random(). That might be okay if you are using them as a source of a lot of randomness but if you are just using them for some cryptograpy work then there is a risk that whatever they are doing (Isaac, Mersenne Twister) isn't random enough initially when seeded by Math.random() which might not be random at all in an old browser.

Recommendation

The doc at the link above reminds me that:

The isaac prng is seeded by hashing together Math.random(), new Date() and any window.cookie. Java webservers like Jetty and Tomcat use cryptographically secure random numbers to create a JSESSIONID cookie that will help seed the generator by default. You can optionally choose to explicitly set a cookie containing a secure random number on the login page to assist in seeding the fallback generator. Upon page load the isaac prng is spun forwards for 100ms. This is because the known vulnerability of isaac is that if the seed is too uniform the early numbers are not well diffused. In addition the random numbers are SHA256 hashed with new Date() to ensure that numbers won't repeat between login attempts.

That is a lot of protection given the rest of the discussion in that doc about how SRP uses random number generators.

My recommendation is set a cryptographically strong random value into some arbitrary cookie and delete the code that is doing additional warm-up when the user types their email. Also if you are aiming for very good security simply don't allow users to login from old browsers that don't support crypo random numbers (see doc about how to test that). Back when thinbus was first written that might have been a lot of corporate users on WindowsXP. Today in 2018 it shouldn't be that inconvenient.