JavaScript SecureRandom() isn’t securely random — many old web wallets affected — and the bug was warned of five years ago (UPDATED)

Update: The word “Most” in the original title of this post is incorrect — see details at end.

Cryptography is profoundly unforgiving of errors. You don’t mess with it. You don’t roll your own — you need battle-hardened algorithms that have been torture-tested by the most technically ruthless cryptographers you can find.

And you stop using old cryptographic algorithms that have known weaknesses. And you fix this sort of thing straight away.

Unless you’re in cryptocurrency, apparently.

The popular JavaScript SecureRandom() library … isn’t securely random.

It will generate cryptographic keys that, despite their length, have less than 48 bits of entropy — since JavaScript isn’t type safe, there’s a bug in SecureRandom() such that it fails to use the browser’s window.crypto … so it falls back to the cryptographically insecure Math.random(), which is only pseudo-random, and can generate no more than 248 different values— so its output will have no more than 48 bits of entropy even if its seed has more than that (which is unlikely). SecureRandom() then runs the number it gets through the obsolete RC4 algorithm, which is known to be more predictable than it should be, i.e. less bits of entropy. Thus, your key is more predictable:

The conclusion seems to be that at least all wallets generated by js tools inside browsers since bitcoin exists until 2011 are impacted by the Math.random weakness if applicable to the related implementations, the Math.random or RC4 (Chrome) weakness between 2011 and 2013, and RC4 weakness for Chrome users until end of 2015

And all wallets using jsbn are impacted by Math.random and RC4 until 2013 (or end 2015 for Chrome), then still by the RC4 fallback step after

What that means is that the keys will be predictable enough to crack by sheer brute-force attack of computing power. You might think you have a key long enough that it can’t be cracked before the sun goes out — but it turns out you could do it in a week.

So a lot of browser-based cryptocurrency products that still use SecureRandom() are generating keys that are open to being cracked.

Check with your product’s author or vendor — there’s a real mess to clean up here.

Like all good cryptocurrency bugs, this one isn’t new at all — here’s Greg Maxwell talking about it nearly three years ago (51:00 on):



And here’s Bitcointalk user Ditto talking about the RC4 bit in March 2013: “Patch the window.SecureRandom function, or the ArcFour PRNG inside it.” And note the response:



Why is cryptocurrency software like this.

(you know why)

Update: EVERYBODY DON’T PANIC!! (cough) This basically affects you if you (a) use old cryptocurrency addresses (b) that were generated with JavaScript, i.e., in a web browser. Move your funds out of those addresses and don’t use them again.

Possibly affected:

  • BitAddress pre-2013;
  • bitcoinjs before 2014;
  • current software that uses old repos they found on Github.

Recent JavaScript-generated addresses probably aren’t affected. But cryptographers consider JavaScript an inappropriate and imprecise language to use for such a critical and brittle use case as key generation. So don’t generate keys in JavaScript at all, and you should probably move your funds out of JavaScript-generated addresses anyway.

Also, check what your web wallet’s author or vendor says about this one.

Become a Patron!

Your subscriptions keep this site going. Sign up today!

2 Comments on “JavaScript SecureRandom() isn’t securely random — many old web wallets affected — and the bug was warned of five years ago (UPDATED)”

  1. I can’t find anywhere any source about “most web wallets”.

    The original e-mail in the Bitcoin mailing list didn’t include which web wallets are affected, neither did other posts about it.

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.