dbsights wrote:Basically, random number generation without linux sucks.
In my opinion, Linux > Windows when it comes to web servers. Microsoft is gaining popularity more and more with its free IIS, but it still lacks in certain aspects. You can, however, use Windows' built-in RNG, which is installed on each Windows based machine. Press Start -> Run and type services.msc and look for Cryptographic Services. If you can find it, your machine supports CSP. (
http://msdn.microsoft.com/en-us/library ... S.85).aspx). On 32-bit systems, you can simply use PHP's COM object to initialize the appripriate CSP object and create strong random data, which I have analyzed to be even stronger than /dev/urandom in many tests. However, on 64-bit systems you are out of luck. As far as I can tell, on 64-bit Windows systems there is no way to generate strong random data without using third-party applications (outsourcing). MSDN has a .NET component, which seems to deliver strong bytes from the CSP, but thanks to PHP - PHP is unable to use 64-bit NET components that has to work with VARIANTs.
Keep in mind one thing: hashes & ciphers != RNGs. If you want good entropy, good randomness and unpredictability, don't use hashes and don't encrypt anything.
The use of HMACs, hashes and uniqid's actually make you lose entropy. You should simply For loop and generate a char from chr(mt_rand()+...) where ... is a list of "random" sources. Never concat anything into the set, always sum up. Don't do chr(mt_rand().another_random_source()) it will make you lose entropy a lot. You need to plus it (sum up) and then use a modulos % 255 to make it within the acceptable character range.
There are several things you could use to generate "random" data.
microtime() - probably most known way. However, I would never use more than the last 4 digits of it as I have noticed how non-random results you get by using the entire value. Also, in tight loops this becomes not so random.
getmypid() - gets the process ID, which is rather random, but it doesn't change until you reload the page (aka execute the script again).
memory_get_usage() - has weak avalance -type effect and is too predictable due to nondynamicness of the value. If you use it, take only last 2 bytes of it.
Since you can use COM on Windows 32-bit, and /dev/urandom on Unix -like systems, the only situation where you basically have to use your own RNG is on a Windows machine. So, you could read random (mt_rand()) files on the system root and read their data statistics. Then do something like:
Code: Select all
$stat = stat('a_randomly_chosen_windows_root_file');
$more = $stat[7]+substr($stat[8],-3,3)+substr($stat[9],-3,3)+substr($stat[10],-3,3))
And again, you would sum the $more into the mt_rand() and others. I used substr() to take only the last bytes as the whole value, again, is not very random. To do even better, you could read server log file info or the system temp or anywhere you have lots of files which are frequently accessed or changed.
Or you could read
http://www.random.org for random data, but the random data is transferred over the network in plain-text format and you are not the only one who knows the random data..
Basically, on a 64-bit Windows server you are more or less out of luck for now. In the future, PHP has openssl_get_pseudo_bytes() or similar function that will rescue us and hopefully PHP fixes the NET component bugs, too, which have existed for years.

(
http://bugs.php.net/bug.php?id=41286)
OpenSSL has a quite cool way to generate random data - by hashing the screen content among with several other wicked details (mostly hardware related).
I'm not entirely sure what is your problem with sessions or caching, but does it have something to do with locking? You can lock files with flock() and (My)SQL offer their equivalents depending on the RDBMS and the used storage engine. (
http://search.mysql.com/search?site=ref ... lr=lang_en)