PageRenderTime 49ms CodeModel.GetById 22ms RepoModel.GetById 0ms app.codeStats 0ms

/libraries/joomla/crypt/crypt.php

https://bitbucket.org/asosso/joomla15
PHP | 153 lines | 90 code | 10 blank | 53 comment | 15 complexity | 43cdba7d64365cb00ae6a172f08d49f6 MD5 | raw file
Possible License(s): LGPL-2.1, Apache-2.0
  1. <?php
  2. /**
  3. * @version $Id: crypt.php 22952 2012-03-27 00:40:16Z dextercowley $
  4. * @package Joomla.Platform
  5. * @subpackage Crypt
  6. *
  7. * @copyright Copyright (C) 2005 - 2012 Open Source Matters, Inc. All rights reserved.
  8. * @license GNU General Public License version 2 or later; see LICENSE
  9. */
  10. defined('JPATH_BASE') or die();
  11. /**
  12. * JCrypt is a Joomla Platform class for handling basic encryption/decryption of data.
  13. *
  14. * @package Joomla.Platform
  15. * @subpackage Crypt
  16. * @since 12.1
  17. */
  18. class JCrypt
  19. {
  20. /**
  21. * Generate random bytes.
  22. *
  23. * @param integer $length Length of the random data to generate
  24. *
  25. * @return string Random binary data
  26. *
  27. * @since 12.1
  28. * @note This method requires PHP 5
  29. */
  30. function genRandomBytes($length = 16)
  31. {
  32. $sslStr = '';
  33. /*
  34. * if a secure randomness generator exists and we don't
  35. * have a buggy PHP version use it.
  36. */
  37. if (
  38. function_exists('openssl_random_pseudo_bytes')
  39. && (version_compare(PHP_VERSION, '5.3.4') >= 0
  40. || substr(PHP_OS, 0, 3) !== 'WIN'
  41. )
  42. )
  43. {
  44. $sslStr = openssl_random_pseudo_bytes($length, $strong);
  45. if ($strong)
  46. {
  47. return $sslStr;
  48. }
  49. }
  50. /*
  51. * Collect any entropy available in the system along with a number
  52. * of time measurements of operating system randomness.
  53. */
  54. $bitsPerRound = 2;
  55. $maxTimeMicro = 400;
  56. $shaHashLength = 20;
  57. $randomStr = '';
  58. $total = $length;
  59. // Check if we can use /dev/urandom.
  60. $urandom = false;
  61. $handle = null;
  62. if (function_exists('stream_set_read_buffer') && @is_readable('/dev/urandom'))
  63. {
  64. $handle = @fopen('/dev/urandom', 'rb');
  65. if ($handle)
  66. {
  67. $urandom = true;
  68. }
  69. }
  70. while ($length > strlen($randomStr))
  71. {
  72. $bytes = ($total > $shaHashLength)? $shaHashLength : $total;
  73. $total -= $bytes;
  74. /*
  75. * Collect any entropy available from the PHP system and filesystem.
  76. * If we have ssl data that isn't strong, we use it once.
  77. */
  78. $entropy = rand() . uniqid(mt_rand(), true) . $sslStr;
  79. $entropy .= implode('', @fstat(fopen( __FILE__, 'r')));
  80. $entropy .= memory_get_usage();
  81. $sslStr = '';
  82. if ($urandom)
  83. {
  84. stream_set_read_buffer($handle, 0);
  85. $entropy .= @fread($handle, $bytes);
  86. }
  87. else
  88. {
  89. /*
  90. * There is no external source of entropy so we repeat calls
  91. * to mt_rand until we are assured there's real randomness in
  92. * the result.
  93. *
  94. * Measure the time that the operations will take on average.
  95. */
  96. $samples = 3;
  97. $duration = 0;
  98. for ($pass = 0; $pass < $samples; ++$pass)
  99. {
  100. $microStart = microtime(true) * 1000000;
  101. $hash = sha1(mt_rand(), true);
  102. for ($count = 0; $count < 50; ++$count)
  103. {
  104. $hash = sha1($hash, true);
  105. }
  106. $microEnd = microtime(true) * 1000000;
  107. $entropy .= $microStart . $microEnd;
  108. if ($microStart > $microEnd) {
  109. $microEnd += 1000000;
  110. }
  111. $duration += $microEnd - $microStart;
  112. }
  113. $duration = $duration / $samples;
  114. /*
  115. * Based on the average time, determine the total rounds so that
  116. * the total running time is bounded to a reasonable number.
  117. */
  118. $rounds = (int)(($maxTimeMicro / $duration) * 50);
  119. /*
  120. * Take additional measurements. On average we can expect
  121. * at least $bitsPerRound bits of entropy from each measurement.
  122. */
  123. $iter = $bytes * (int) ceil(8 / $bitsPerRound);
  124. for ($pass = 0; $pass < $iter; ++$pass)
  125. {
  126. $microStart = microtime(true);
  127. $hash = sha1(mt_rand(), true);
  128. for ($count = 0; $count < $rounds; ++$count)
  129. {
  130. $hash = sha1($hash, true);
  131. }
  132. $entropy .= $microStart . microtime(true);
  133. }
  134. }
  135. $randomStr .= sha1($entropy, true);
  136. }
  137. if ($urandom)
  138. {
  139. @fclose($handle);
  140. }
  141. return substr($randomStr, 0, $length);
  142. }
  143. }