3

128-bit entropy is required

http://nxtra.org/nxt-client/js/passphrasegenerator.js

With all new browsers (Chrome, Firefox, IE 11) it uses crypto.getRandomValues which should be safe, but with IE 10 (and older) it uses random mouse input from the user combined with Math.random

$("html").on("mousemove", function(e) {
            var seed = [e.pageX, e.pageY, +new Date];
            PassPhraseGenerator.push(seed);

How safe is that second part?

user12480
  • 195
  • 1
  • 6
  • It appears to be reasonably secure passphrase. Granted it doesn't use https, so it would be trivial for any network eavesdropper to capture your passphrase by tampering with the http scripts on nxtra.org to something that exposes the passphrase to them. – dr jimbob Mar 19 '14 at 04:54
  • It's not running https as it's in beta version running on testNet. As I understand it, the final version would be downloadable and run locally. Online implementations would probably include https – user12480 Mar 19 '14 at 22:19

2 Answers2

2

In on itself it should be fairly secure as a concept, but generally speaking one should not rely on JavaScript for any kind of security. It's trivially easy to do injections and interceptions on any JavaScript code and doing complex math in JavaScript can easily trigger 'stop script' or any other browser script sanity checks so developers tend to either lower the security as much as possible or to downright break any convention just so their 'secure page' can work - which in turn leads to all kinds of problems.

But putting that aside, there are two potential problems I see with this particular implementation:

1. The word list is way too small - it picks randomly 12 words out of pool with only 1626 words which makes mere ~7.42x10^29 possible combinations assuming that the random is truly random. That's fairly lower than 128 bits of entropy (~3.4x10^38) - in fact almost half a billion times lower, so even with the assumption of true randomness or using the browser's crypto facilities you're getting at best 99 bits of entropy. Either increase the word list to ~8400 words or pick 17 words instead of 12 if you're aiming at 128 bit. (Disregard this part, it applies only to unique pass generation.)

2. Relying on the user to generate sufficiently safe seed can easily break any security. Users are by definition lazy, and having them to move their mouse can end up in repetitive left-right movement over a small area (usually near the 'generate password' field) which can be exploited to lower the probability of picking some of the combinations at random. I'd add at least a delta check (if(Math.abs(lastX - e.pageX) < 20 || Math.abs(lastY - e.pageY)) return; ...) to force the users to move their mouse a bit more randomly. It wouldn't hurt to use some of the browser stats apart from the new Date to add to the seed as well.

BeagleEagle
  • 194
  • 5
  • 2
    A passphrase consisting of 12 words picked from a list of 1626 different words with uniform distribution has 128.005 bits of entropy. `12 * log2(1625)` – CodesInChaos Mar 19 '14 at 10:36
  • I stand corrected, I was calculating for ordered word picking (`log2(1626^12 / 12!)`). – BeagleEagle Mar 19 '14 at 12:11
  • 1
    Abysmal answer. JavaScript can be used to implement cryptography just like any other language. Stop scripts are not a problem for this. Pretty much the only thing JavaScript can't do is replace HTTPS, as JavaScript inherently can't secure itself from being manipulated during transmission. – aaaaaaaaaaaa Mar 19 '14 at 13:10
  • The code secures 512 data points from mouse movement, so to generate 128 bits of entropy we need at least an average of 1/4 bit from each data point. The code take both mouse position and time, during slow mouse movement the exact time difference between the individual data points will vary a bit, and during fast mouse movement the difference in position will vary a bit. There is no way for a human to move a mouse without generating good entropy in at least one of these ways. The requirement of 512 data points is in my opinion very far on the safe side. – aaaaaaaaaaaa Mar 19 '14 at 13:16
  • Even if you had been correct about the final password only containing 99 bits of entropy it would still be a very strong password. Someone who can try a billion passwords a second would need 20 trillion years to get through the lot. – aaaaaaaaaaaa Mar 19 '14 at 13:25
1

The second method relies on this library: http://nxtra.org/nxt-client/js/seedrandom.js

It is a pain to read that code, but I think I can confirm that it is at least good enough for the job. The important parts are that there is a plenty big entropy pool, the code ensures that enough entropy is gathered, the whitening function scrambles the gathered entropy decently, the random generator is unbiased, and it uses a sufficiently large part of the entropy pool.

By far the biggest potential worry for that site would be lack of HTTPS, meaning that the login in any case should only be considered good enough for a low security site.

aaaaaaaaaaaa
  • 1,027
  • 6
  • 8
  • the final version would be downloadable and run locally on the computer. Online implementations would probably include https – user12480 Mar 19 '14 at 22:28
  • @user12480 What is your interest in this generator? I would have used a longer word list and a shorter output, since 12 words is quite a lot both to remember and type. The insistence on 128 bit entropy in the output is overkill for all purposes. If you are guarding a billion dollar secret with encryption, and brute force testing somehow can be done extremely fast then you might consider an 80 bit password, for a normal website login 40 to 50 bits should be plenty. Less can do with proper login attempt throttling. – aaaaaaaaaaaa Mar 20 '14 at 09:22
  • It's not a "password" for web login. The hash of the password is used to generate a private key for curve25519. Think of it as bitcoin private key. The entropy needs to be at least 128 bits. It's available now as downloadable app from here http://nxtra.org/nxt-wallet/ – user12480 May 15 '14 at 01:21