berthubert / trifecta

educational image sharing website built on a combination of modern C++, web and database technologies
MIT License
149 stars 9 forks source link

Mersenne Twister not suitable for security tokens #41

Closed solardiz closed 9 months ago

solardiz commented 9 months ago

Mersenne Twister is not a CSPRNG. Given enough (partial) outputs (a few kilobytes), its internal state is practical to infer (even if the seed space is large), and then further outputs can be predicted. XOR'ing a 64-bit value by the nanoseconds still directly exposes the high 34 bits from the original MT output even if the nanoseconds were not more granular and were completely unpredictable (or more than 34 bits otherwise).

See https://github.com/fx5/not_random which is for Python's 32+32-bit MT, rather than for 64-bit MT (is that what's used here?), but the same concept and similar prerequisites should apply.

Moreover, once the internal state is known, the nanoseconds themselves can be inferred, which I suppose could matter in obscure scenarios such as identifying that a Tor hidden service is running on the same machine as another service (with one of them offering Trifecta). In general, seeding a PRNG with more inputs is always a risk of exposing those inputs - you have to ensure you have enough seed material and you use a CSPRNG not to expose the inputs.

solardiz commented 9 months ago

That was quick, thanks!

I wonder if there exist relevant implementations of std::random_device that use /dev/random rather than /dev/urandom. That would be a problem, as we don't want a web app to block.

berthubert commented 9 months ago

Thanks - I did not realize the state could be recovered this easily. https://en.cppreference.com/w/cpp/numeric/random/random_device/random_device has some details on devices that could be used. If this blocks I'm sure I'll hear about it.