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

Reply via email to