Navigation Menu

Skip to content

Commit

Permalink
Beef up the random number generator by using Joomla's new implementat…
Browse files Browse the repository at this point in the history
…ion.
  • Loading branch information
bharat committed Apr 1, 2012
1 parent b9d7ad2 commit cd46dc4
Show file tree
Hide file tree
Showing 3 changed files with 158 additions and 5 deletions.
6 changes: 4 additions & 2 deletions modules/gallery/helpers/random.php
Expand Up @@ -17,13 +17,15 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA.
*/

class random_Core {
/**
* Return a random 32 byte hash value.
* @param string extra entropy data
*/
static function hash($entropy="") {
return md5($entropy . uniqid(mt_rand(), true));
static function hash($length=32) {
require_once(MODPATH . "gallery/vendor/joomla/crypt.php");
return md5(JCrypt::genRandomBytes($length));
}

/**
Expand Down
151 changes: 151 additions & 0 deletions modules/gallery/vendor/joomla/crypt.php
@@ -0,0 +1,151 @@
<?php defined("SYSPATH") or die("No direct script access.");
/**
* @package Joomla.Platform
* @subpackage Crypt
*
* @copyright Copyright (C) 2005 - 2011 Open Source Matters, Inc. All rights reserved.
* @license GNU General Public License version 2 or later; see LICENSE
*/

// defined('JPATH_PLATFORM') or die;

/**
* JCrypt is a Joomla Platform class for handling basic encryption/decryption of data.
*
* @package Joomla.Platform
* @subpackage Crypt
* @since 12.1
*/
class JCrypt
{
/**
* Generate random bytes.
*
* @param integer $length Length of the random data to generate
*
* @return string Random binary data
*
* @since 12.1
*/
public static function genRandomBytes($length = 16)
{
$sslStr = '';
/*
* if a secure randomness generator exists and we don't
* have a buggy PHP version use it.
*/
if (
function_exists('openssl_random_pseudo_bytes')
&& (version_compare(PHP_VERSION, '5.3.4') >= 0
|| substr(PHP_OS, 0, 3) !== 'WIN'
)
)
{
$sslStr = openssl_random_pseudo_bytes($length, $strong);
if ($strong)
{
return $sslStr;
}
}

/*
* Collect any entropy available in the system along with a number
* of time measurements of operating system randomness.
*/
$bitsPerRound = 2;
$maxTimeMicro = 400;
$shaHashLength = 20;
$randomStr = '';
$total = $length;

// Check if we can use /dev/urandom.
$urandom = false;
$handle = null;
if (function_exists('stream_set_read_buffer') && @is_readable('/dev/urandom'))
{
$handle = @fopen('/dev/urandom', 'rb');
if ($handle)
{
$urandom = true;
}
}

while ($length > strlen($randomStr))
{
$bytes = ($total > $shaHashLength)? $shaHashLength : $total;
$total -= $bytes;
/*
* Collect any entropy available from the PHP system and filesystem.
* If we have ssl data that isn't strong, we use it once.
*/
$entropy = rand() . uniqid(mt_rand(), true) . $sslStr;
$entropy .= implode('', @fstat(fopen( __FILE__, 'r')));
$entropy .= memory_get_usage();
$sslStr = '';
if ($urandom)
{
stream_set_read_buffer($handle, 0);
$entropy .= @fread($handle, $bytes);
}
else
{
/*
* There is no external source of entropy so we repeat calls
* to mt_rand until we are assured there's real randomness in
* the result.
*
* Measure the time that the operations will take on average.
*/
$samples = 3;
$duration = 0;
for ($pass = 0; $pass < $samples; ++$pass)
{
$microStart = microtime(true) * 1000000;
$hash = sha1(mt_rand(), true);
for ($count = 0; $count < 50; ++$count)
{
$hash = sha1($hash, true);
}
$microEnd = microtime(true) * 1000000;
$entropy .= $microStart . $microEnd;
if ($microStart > $microEnd) {
$microEnd += 1000000;
}
$duration += $microEnd - $microStart;
}
$duration = $duration / $samples;

/*
* Based on the average time, determine the total rounds so that
* the total running time is bounded to a reasonable number.
*/
$rounds = (int)(($maxTimeMicro / $duration) * 50);

/*
* Take additional measurements. On average we can expect
* at least $bitsPerRound bits of entropy from each measurement.
*/
$iter = $bytes * (int) ceil(8 / $bitsPerRound);
for ($pass = 0; $pass < $iter; ++$pass)
{
$microStart = microtime(true);
$hash = sha1(mt_rand(), true);
for ($count = 0; $count < $rounds; ++$count)
{
$hash = sha1($hash, true);
}
$entropy .= $microStart . microtime(true);
}
}

$randomStr .= sha1($entropy, true);
}

if ($urandom)
{
@fclose($handle);
}

return substr($randomStr, 0, $length);
}
}
6 changes: 3 additions & 3 deletions modules/rest/helpers/rest_event.php
Expand Up @@ -43,7 +43,7 @@ static function change_provider($new_provider) {
static function user_add_form_admin_completed($user, $form) {
$key = ORM::factory("user_access_key");
$key->user_id = $user->id;
$key->access_key = random::hash($user->name);
$key->access_key = random::hash();
$key->save();
}

Expand All @@ -64,7 +64,7 @@ static function _get_access_key_form($user, $form) {

if (!$key->loaded()) {
$key->user_id = $user->id;
$key->access_key = random::hash($user->name);
$key->access_key = random::hash();
$key->save();
}

Expand Down Expand Up @@ -93,7 +93,7 @@ static function show_user_profile($data) {

if (!$key->loaded()) {
$key->user_id = $data->user->id;
$key->access_key = random::hash($data->user->name);
$key->access_key = random::hash();
$key->save();
}
$view->rest_key = $key->access_key;
Expand Down

0 comments on commit cd46dc4

Please sign in to comment.