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.

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):

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.

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.

About

The content of this site is journalism and personal opinion. Nothing contained on this site is, or should be construed as providing or offering, investment, legal, accounting, tax or other advice. Do not act on any opinion expressed here without consulting a qualified professional. I do not hold a position in any crypto asset or cryptocurrency or blockchain company.