paypal / seifnode

MIT License
545 stars 41 forks source link

Recommendation: Use the OS-provided random number generator #1

Closed zofrex closed 8 years ago

zofrex commented 9 years ago

This project uses its own CSPRNG and deals with gathering entropy to seed it. I strongly recommend against this. This is work that is already done for you by any decent operating system, and the OS kernel is in a much better position to do so:

On Unix and Linux systems, the right answer is to read from /dev/urandom (or use the getrandom() syscall on newer Linux kernels - but urandom is still fine to use). On Windows, you can use CryptGenRandom.

Citations:

How To Safely Generate Random Numbers - citation to use /dev/urandom, this is very biased towards Linux but makes a small mention of OS X and BSD Myths About /dev/urandom - goes into a lot more detail about how /dev/(u)random works and dispells many common falsehoods about it Thomas Ptacek telling me to use CryptGenRandom on Windows - best citation I have to hand for what to use on Windows

RoyTinker commented 9 years ago

Doesn't /dev/urandom seed from a 256-bit entropy pool by default?

As I understand it, the seif web is interested in seeding from much larger entropy pools, which could only be obtained quickly from hardware RNGs, of which cameras and microphones are the most popular and widespread variants.

aashish-sheshadri commented 9 years ago

@zofrex thanks for your input -- our first choice was to just use the OS random number generator. However we are looking at using this to generate 521-bit ECC public keys and 256-bit AES secrets (possibly longer).

Taking that into consideration and the fact that we use the bytes mainly for crypto services we needed a random number generator with a long period and large state space. We therefore decided to use a CPRNG enabling our requirements.

The CPRNG in use needs 16MB of random data to seed -- The OS entropy does not meet this requirement and hence we need other hardware sources to enable such a pool.

zofrex commented 9 years ago

As far as I know, the OS random number generator is suitable for those applications. It's standard to generate public keys using /dev/urandom, and urandom is most definitely suitable for crypto services in general.

mreinstein commented 9 years ago

from the link:

What about entropy running low

The underlying cryptographic building blocks are designed such that an
attacker cannot predict the outcome, as long as there was enough 
randomness in the beginning. A usual lower limit for “enough” may 
be 256 bits. No more.

also from the link:

About 256 bits of entropy are enough to get computationally secure 
numbers for a long, long time

I don't know if these are compelling answers. It sounds like the author is arguing that 256 bits of entropy is enough, and that may not be true for 521-bit ECC keys.

zofrex commented 9 years ago

(NB: In this comment I'm using the term "true random" to include both true randomness such as nuclear decay, and the pretty-close-to-true-randomness signals commonly used by computers, such as those that seed urandom and indeed the CSPRNG in seif)

It's important not to mix up the amount of (actual, true random) entropy needed to seed the RNG (256 bits) and the amount of (cryptographically secure pseudo random) entropy needed to generate a key (which doesn't actually bear any resemblance to the amount of bits the key itself is, incidentally).

Unless you are using something like a one-time pad, you don't benefit from using true random numbers - you only need numbers that are unpredictable enough for cryptographic purposes. Seeding a CSPRNG with sufficient true random bits (the 256 bits you mention) means we can keep using that CSPRNG until the cows come home for things like ECC - we get unlimited useful pseudorandom bits from it!

It doesn't matter if we're talking about 256-bit AES keys, 521-bit ECC keys, or 2048-bit RSA keys - you can get enough bits from urandom. The numbers are the same dimensions (bits) but there isn't a relation such as "you need 2048 bits of true randomness seeding your CSPRNG to generate a 2048 bit RSA key".

It sounds like the author is arguing that 256 bits of entropy is enough

Yes, 256 bits read from a random device would not be enough to create a 521-bit ECC key, but that's not what they're arguing it's enough for. They're arguing that 256-bits of true entropy is enough to generate much, much more than 256 bits of computationally secure random numbers, and you use those bits to create your keys.

Slightly tangential, but also from the article:

while appeal to authority is usually nothing to be proud of, in cryptographic issues you're generally right to be careful and try to get the opinion of a domain expert

Many of the cryptographic choices made by this project are extremely unusual. As a first-order approximation, unusual is not good when it comes to crypto. Cryptography is an area which absolutely needs input from domain experts. I am not an expert on cryptography, but this project needs one involved if it is going to make its own crypto decisions and achieve its aims of security.

SN4T14 commented 8 years ago

Why was this closed? This is a massive issue that urgently needs fixing.

mreinstein commented 8 years ago

@SN4T14 see #3

SN4T14 commented 8 years ago

@mreinstein #3 is suggesting using a different user-space CSPRNG, not removing the user-space CSPRNG altogether, which is the correct course of action.

mreinstein commented 8 years ago

see the comment from Aashish on Nov 3rd earlier in this thread.

SN4T14 commented 8 years ago

@mreinstein @zofrex already responded to that, with very valid criticism, Aashish just closed the issue without further comment after that.

douglascrockford commented 8 years ago

zofrex argues that any decent operating system will provide all of the random services that we need. My concern is not with any, but with every. zofrex and SN4T14 are insisting that I fully trust every operating system to provide all of my random services, including operating systems from all vendors, in all configurations, including all versions, including versions which do not exist yet.

I am unable to trust that which I cannot possibly test.

So I will use the randomness provided by the operating systems, because it is generally very good, but I cannot not trust it completely. And by blending other sources, I do not need to.

joepie91 commented 8 years ago

So I will use the randomness provided by the operating systems, because it is generally very good, but I cannot not trust it completely. And by blending other sources, I do not need to.

There is a discussion ongoing here that says otherwise.

mreinstein commented 8 years ago

There is a discussion ongoing here that says otherwise.

And none of the core node maintainers seem to be on board with it. In fact, they seem to reinforce what @douglascrockford has already mentioned: randomness services on some OSes are broken, and can't be trusted completely:

http://lwn.net/Articles/633805/rss

joepie91 commented 8 years ago

@mreinstein You have not read the thread carefully enough.

EDIT: And just to clarify this - the Node core maintainers are not experienced cryptographers. The point is the thread, not the project.

sam-github commented 8 years ago

And to clarify, the people suggesting that node not use OpenSSL's PRNG (which is at least in part the work of experienced cryptographers, and is absolutely regularly reviewed by experienced cryptographers for flaws) are also not experienced cryptographers.