random value (used in phpBB)

Discussions of secure PHP coding. Security in software is important, so don't be afraid to ask. And when answering: be anal. Nitpick. No security vulnerability is too small.

Moderator: General Moderators

User avatar
WaldoMonster
Forum Contributor
Posts: 225
Joined: Mon Apr 19, 2004 6:19 pm
Contact:

random value (used in phpBB)

Post by WaldoMonster »

I was looking how phpBB did create random values.
And found this code:

Code: Select all

/**
* Our own generator of random values
* This uses a constantly changing value as the base for generating the values
* The board wide setting is updated once per page if this code is called
* With thanks to Anthrax101 for the inspiration on this one
* Added in phpBB 2.0.20
*/
function dss_rand()
{
	global $db, $board_config, $dss_seeded;

	$val = $board_config['rand_seed'] . microtime();
	$val = md5($val);
	$board_config['rand_seed'] = md5($board_config['rand_seed'] . $val . 'a');
   
	if($dss_seeded !== true)
	{
		$sql = "UPDATE " . CONFIG_TABLE . " SET
			config_value = '" . $board_config['rand_seed'] . "'
			WHERE config_name = 'rand_seed'";
		
		if( !$db->sql_query($sql) )
		{
			message_die(GENERAL_ERROR, "Unable to reseed PRNG", "", __LINE__, __FILE__, $sql);
		}

		$dss_seeded = true;
	}

	return substr($val, 4, 16);
}

I have looked around for dss and random on the internet, but only found phpBB related articles.
Is there a common name for this algorithm?
Is there any website explaining this algorithm?
Or is it a unique phpBB code?
User avatar
feyd
Neighborhood Spidermoddy
Posts: 31559
Joined: Mon Mar 29, 2004 3:24 pm
Location: Bothell, Washington, USA

Post by feyd »

Hashing a previous hash, even padded, is often not recommended. The math doesn't work out well. The reason why is entropy. Hash results have pretty low entropy. Coupled with uniform result length, makes it that much easier.

Honestly, I have to say that is wishful at best.
User avatar
Ollie Saunders
DevNet Master
Posts: 3179
Joined: Tue May 24, 2005 6:01 pm
Location: UK

Post by Ollie Saunders »

what's wrong with mt_rand() for generating random values?
User avatar
WaldoMonster
Forum Contributor
Posts: 225
Joined: Mon Apr 19, 2004 6:19 pm
Contact:

Post by WaldoMonster »

ole wrote:what's wrong with mt_rand() for generating random values?
What I read from the Internet that there is no real random generator for PHP.
Many articles conclude that mt_rand() is better than rand().
I found this an interesting article:
http://portfolio.technoized.com/notes/26
User avatar
feyd
Neighborhood Spidermoddy
Posts: 31559
Joined: Mon Mar 29, 2004 3:24 pm
Location: Bothell, Washington, USA

Post by feyd »

Mersenne Twist sequences have far longer runs before repeating than those used by rand(). This is their benefit, however they will repeat eventually.

Truly random data isn't readily available in most operating environments unfortunately. /dev/urandom is a good source for high entropy on many Linux systems. There are services available online that provide truly random streams when random number generation is required.
User avatar
AKA Panama Jack
Forum Regular
Posts: 878
Joined: Mon Nov 14, 2005 4:21 pm

Post by AKA Panama Jack »

I use this...

Code: Select all

mt_srand(hexdec(substr(md5(microtime()), -8)) & 0x7fffffff);

$random_number = mt_rand(1, $whatever);
Using the algorithm above to reset the seed for mt_rand seems to work perfectly as I haven't had any sequence ever repeat.
User avatar
Mordred
DevNet Resident
Posts: 1579
Joined: Sun Sep 03, 2006 5:19 am
Location: Sofia, Bulgaria

Post by Mordred »

You don't need to seed the mt_rand, it's autoseeded for you on script start, and I suspect that it's better than your seeding with all those fishy md5/substr calls. Every time you hash something its entropy diminishes, so why do it at all?
User avatar
Maugrim_The_Reaper
DevNet Master
Posts: 2704
Joined: Tue Nov 02, 2004 5:43 am
Location: Ireland

Post by Maugrim_The_Reaper »

Older PHP versions require mt_srand() for seeding. Has not been required for a long time though, so BC is the only reason for this. Hashing should be avoided for seeds - see feyd's earlier comments. For most uses mt_rand() should suffice without much interference, the period is large enough for the majority for applications.

phpBB's code is...odd. Not sure what all that jumping through hoops is going to accomplish except a lot of head scratching...;).
User avatar
Ollie Saunders
DevNet Master
Posts: 3179
Joined: Tue May 24, 2005 6:01 pm
Location: UK

Post by Ollie Saunders »

phpBB's code is...[s]odd[/s] poop

fixed
User avatar
AKA Panama Jack
Forum Regular
Posts: 878
Joined: Mon Nov 14, 2005 4:21 pm

Post by AKA Panama Jack »

Mordred wrote:You don't need to seed the mt_rand, it's autoseeded for you on script start, and I suspect that it's better than your seeding with all those fishy md5/substr calls. Every time you hash something its entropy diminishes, so why do it at all?
True it is automatically seeded on PHP 4.2.0 and higher but if your program is still compatible with versions of PHP older than 4.2 it is best to reseed the random number generators your self. And as I mentioned from my testing the reseeding method I mentioned hasn't given any duplicate random number sequences so it seems to do it's job quite well. :)
User avatar
Ollie Saunders
DevNet Master
Posts: 3179
Joined: Tue May 24, 2005 6:01 pm
Location: UK

Post by Ollie Saunders »

Have you tried those same tests with just calling mt_rand()?
User avatar
WaldoMonster
Forum Contributor
Posts: 225
Joined: Mon Apr 19, 2004 6:19 pm
Contact:

Post by WaldoMonster »

Thanks all for the feedback.
I still have a related question.
Is there a difference in randomness between?

Code: Select all

// Contacting 40x (1 digit base36)
mt_rand(0,36-1)

// Contacting 8x (36^5-1 = 5 digits base36)
mt_rand(0, 60466176-1);
User avatar
feyd
Neighborhood Spidermoddy
Posts: 31559
Joined: Mon Mar 29, 2004 3:24 pm
Location: Bothell, Washington, USA

Post by feyd »

There's a difference in the range, so yes.

mt_getrandmax() should also be used to make sure you don't set a value too high.
User avatar
WaldoMonster
Forum Contributor
Posts: 225
Joined: Mon Apr 19, 2004 6:19 pm
Contact:

Post by WaldoMonster »

feyd wrote:There's a difference in the range, so yes.

mt_getrandmax() should also be used to make sure you don't set a value too high.
Is it better to concat less large mt_rand() within the mt_getrandmax() range
or concat more small mt_rand() with the same total length?
(see example above)
User avatar
feyd
Neighborhood Spidermoddy
Posts: 31559
Joined: Mon Mar 29, 2004 3:24 pm
Location: Bothell, Washington, USA

Post by feyd »

What I typically will do is use mt_rand() with mt_getrandmax() to build a decimal value. I then multiply the decimal value by the end scale to reach the actual value. It will have rounding errors for very large ranges, but that's fairly unless you have access to even better random streams.
Post Reply