Tom, First off, /dev/random doesn't report anything. If the entropy pool is depleted, it will block until it has enough entropy to fufil the request. That may seem good, but it's a HUGE DOS vulnerability if you are using them for non CS applications (which the VAST majority of PHP applications fall into).
Secondly, you seem to be under the impression that you can secure anything on a shared host. The truth is that by very nature a shared host will always by cryptographically insecure. That's because you don't have access to the underlying system. Not running the very latest kernel? You're not secure. Having applications on the same server that hit the CS entropy pool unnecessarially? That's not secure. If you don't have access to the config, it's not secure (since someone can chroot your vhost, and point /dev/random to another compromised entropy source)... In short, if you don't control the system from the top to bottom, you can't have cryptographic level security... With that said, > The entropy coming out of the mixer cannot be bigger than the entropy > going in. A good mixer is important if you have more than one source of > real entropy and need to combine them. I do not believe this is the case > here. Correct, however it can be bigger than any single piece of entropy going in. Which is the key point. If you mix 12 random numbers, each with 1 bit of randomness, you can theoretically get as high as 12 bits of entropy out of the mixed number (theoretically, the actual number depends on a lot of factors)... > mt_rand() and rand() are not random in any CS sense so the entropy they > contribute should be counted as zero. In the situations we are discussing, > uniqid() also adds no entropy because it fall back on the same microtime() > that you have in your function. So the entropy going into the mixer is > whatever you you think microtime() provides. Considering unknown clock > resolution and that digits above 100ms, say, are predictable, maybe 20 to > 25 bits? Not much more anyway. Best you can do is reply to the caller with > 2 or 3 bytes of result based on that. But now you have to refuse > subsequent calls because microtime() will give no more entropy unless the > time between calls to it are truly random. Implemented independently, yes you are correct. But each can increase the entropy of the result in a mixed mode (which is what the RFC was talking about). In the case of the mixed function, you would need to know the current state of every single source to compromise the next number. And you'd need to know the rolling state as well (PHP uses the same internal state for all threads, so if you're using multi-threaded SAPI like FastCGI or mod_php, knowing the state now, doens't mean you'll know it later in the same process thread)... So it satisfies both criteria to be Cryptographically Secure. Now, I'm not saying it is CS (if I really needed that, I would use a FIPS certified kernel level generator), but it is by far the best you'll get in PHP without having full control over the system (in fact, I'd go as far to say that on a shared host, mixing those sources will likely be more trustable than /dev/random will be, in the worst case scenario)... > CryptGenRandom is a FIPS verified CSPRNG. I am no cryptographer or > security expert but I would not attempt to pass off mixing up microtime() > to anyone that is. If you're implementing applications that require FIPS certification, you're not doing it on a shared host either. So that argument is moot. I'm not trying to talk up anything else, or talk down CryptGenRandom. Instead, I'm pointing out that achieving an acceptable quality RN for **MOST** uses should not call CryptGenRandom. Instead, it should use PseudoRandom numbers. I tried to avoid the Ad Hominem argument (if anything sounded like that, please forgive me). I hope that clarifies things from my point of view... On Wed, Dec 28, 2011 at 4:11 PM, Tom Worster <f...@thefsb.org> wrote: > Hi Anthony, > > Thanks again for your time responding. > > > On 12/21/11 2:35 PM, "Anthony Ferrara" <ircmax...@gmail.com> wrote: > >>Tom, >> >>> I think it nicely demonstrates a degree of sophistication that should >>> not be expected from typical PHP usrs. >> >>Which is why it should be available in a library of some form. Could >>it be in core? Absolutely. Does it need to be? Nope... > > Under the hood there is php_win32_get_random_bytes(). But there is no > consistent way to access it. Rectifying that in PHP is easy and is, in my > view, the right way to get CS random bytes on Windows. > > >> >>> [I don't think mixing mt_rand() + rand() + uniqid() + microtime() is >>> really much better than mixing only mt_rand() + microtime().] >> >>The key is not the sources, but how they are mixed. The RFC quoted >>shows how to mix in a way that as long as you have one non-compromised >>source, the final output is always at least as random as the strongest >>non-compromised source. In practice it will be significantly stronger >>since most compromises of sources are not total. > > The entropy coming out of the mixer cannot be bigger than the entropy > going in. A good mixer is important if you have more than one source of > real entropy and need to combine them. I do not believe this is the case > here. > > mt_rand() and rand() are not random in any CS sense so the entropy they > contribute should be counted as zero. In the situations we are discussing, > uniqid() also adds no entropy because it fall back on the same microtime() > that you have in your function. So the entropy going into the mixer is > whatever you you think microtime() provides. Considering unknown clock > resolution and that digits above 100ms, say, are predictable, maybe 20 to > 25 bits? Not much more anyway. Best you can do is reply to the caller with > 2 or 3 bytes of result based on that. But now you have to refuse > subsequent calls because microtime() will give no more entropy unless the > time between calls to it are truly random. > > CryptGenRandom is a FIPS verified CSPRNG. I am no cryptographer or > security expert but I would not attempt to pass off mixing up microtime() > to anyone that is. > > >>> 1. PHP users cannot be trusted with access to the system's entropy> >>>pool lest they dangerously deplete it. >>Honestly, if you need to access the system's entropy pool, then go for >>it. But creating a new _rand() function will give easy access without >>any warning or frankly need. I'll explain later... >> >>> 2. Keeping things as they are protects the entropy pool from overuse. >> >>No, it makes it so that it's hard to *accidentally* use the entropy >>pool just because you saw the function somewhere. If you need it, >>it's there... >> >>With respect to the cs_rand() proposal, there is another argument >>against it. In PHP, there's *very* little use for a Cryptographically >>Secure random integers. There are significant uses for random >>strings, but not numbers. Sure, you can convert an integer to a >>string fairly easily. But it's actually pretty hard to do so in a >>manner that maintains the cryptographic security of the values... So >>why add a function that has little direct use, but can be >>significantly abused? Especially when using them for generating >>random strings can be difficult to the point where it's easy to >>generate non-secure strings from a secure source. > > Actually what I want is a function that returns a string of random bytes. > I guess I confused matters with the proposed name. Ideal would be > something identical to openssl_random_pseudo_bytes() but not dependent on > any extension, compile- or run-time option. > > >>If you want to add a cryptographically secure PRNG to PHP, add it so >>that it returns a string of the specified length. But again, I'm >>concerned about adding it since it will be abused. Even your original >>point about salts would abuse such a function. CSPRNs do have >>important uses. But they should NOT be used for cases where you don't >>truly need cryptographic security (as each use reduces the available >>entropy in the system, and can under certain circumstances make other >>secure applications less secure). > > That's reasonable. I am inclined to the view that users who actually need > a CS string should be catered to. Idiot users will always have, and have > always had, the opportunity to spoil the utility of a multi-user system > for the other users. And it should go without saying that they cannot be > protected from themselves. > > Tom > > -- PHP Internals - PHP Runtime Development Mailing List To unsubscribe, visit: http://www.php.net/unsub.php