aboutsummaryrefslogtreecommitdiff
path: root/engine/classes/ElggCrypto.php
diff options
context:
space:
mode:
authorSteve Clay <steve@mrclay.org>2013-06-10 23:16:45 -0400
committerPaweł Sroka <srokap@gmail.com>2013-11-04 04:24:47 +0100
commite98f933857548be9cd078416a93011ea9c2f3e3a (patch)
tree1ac16234f014062cd881b3a5c2cab74dc78aba00 /engine/classes/ElggCrypto.php
parent550ef1fe32fc8da940c42359f7a6347e65138c85 (diff)
downloadelgg-e98f933857548be9cd078416a93011ea9c2f3e3a.tar.gz
elgg-e98f933857548be9cd078416a93011ea9c2f3e3a.tar.bz2
Allow regenerating site secret
Diffstat (limited to 'engine/classes/ElggCrypto.php')
-rw-r--r--engine/classes/ElggCrypto.php134
1 files changed, 134 insertions, 0 deletions
diff --git a/engine/classes/ElggCrypto.php b/engine/classes/ElggCrypto.php
new file mode 100644
index 000000000..364af4542
--- /dev/null
+++ b/engine/classes/ElggCrypto.php
@@ -0,0 +1,134 @@
+<?php
+/**
+ * ElggCrypto
+ *
+ * @package Elgg.Core
+ * @subpackage Crypto
+ *
+ * @access private
+ */
+class ElggCrypto {
+
+ /**
+ * Character set for temp passwords (no risk of embedded profanity/glyphs that look similar)
+ */
+ const CHARS_PASSWORD = 'bcdfghjklmnpqrstvwxyz2346789';
+
+ /**
+ * Returns a string of highly randomized bytes (over the full 8-bit range).
+ *
+ * This function is better than simply calling mt_rand() or any other built-in
+ * PHP function because it can return a long string of bytes (compared to < 4
+ * bytes normally from mt_rand()) and uses the best available pseudo-random
+ * source.
+ *
+ * @param int $count The number of characters (bytes) to return in the string.
+ * @return string
+ *
+ * @copyright Copyright 2001 - 2012 by the original authors
+ * https://github.com/drupal/drupal/blob/7.x/COPYRIGHT.txt
+ * @license https://github.com/drupal/drupal/blob/7.x/LICENSE.txt GPL 2
+ *
+ * @see https://github.com/drupal/drupal/blob/7.x/includes/bootstrap.inc#L1942
+ */
+ public static function getRandomBytes($count) {
+ // $random_state does not use drupal_static as it stores random bytes.
+ static $random_state, $bytes, $php_compatible;
+ // Initialize on the first call. The contents of $_SERVER includes a mix of
+ // user-specific and system information that varies a little with each page.
+ if (!isset($random_state)) {
+ $random_state = print_r($_SERVER, true);
+ if (function_exists('getmypid')) {
+ // Further initialize with the somewhat random PHP process ID.
+ $random_state .= getmypid();
+ }
+ $bytes = '';
+ }
+ if (strlen($bytes) < $count) {
+ // PHP versions prior 5.3.4 experienced openssl_random_pseudo_bytes()
+ // locking on Windows and rendered it unusable.
+ if (!isset($php_compatible)) {
+ $php_compatible = version_compare(PHP_VERSION, '5.3.4', '>=');
+ }
+ // /dev/urandom is available on many *nix systems and is considered the
+ // best commonly available pseudo-random source.
+ if ($fh = @fopen('/dev/urandom', 'rb')) {
+ // PHP only performs buffered reads, so in reality it will always read
+ // at least 4096 bytes. Thus, it costs nothing extra to read and store
+ // that much so as to speed any additional invocations.
+ $bytes .= fread($fh, max(4096, $count));
+ fclose($fh);
+ } elseif ($php_compatible && function_exists('openssl_random_pseudo_bytes')) {
+ // openssl_random_pseudo_bytes() will find entropy in a system-dependent
+ // way.
+ $bytes .= openssl_random_pseudo_bytes($count - strlen($bytes));
+ }
+ // If /dev/urandom is not available or returns no bytes, this loop will
+ // generate a good set of pseudo-random bytes on any system.
+ // Note that it may be important that our $random_state is passed
+ // through hash() prior to being rolled into $output, that the two hash()
+ // invocations are different, and that the extra input into the first one -
+ // the microtime() - is prepended rather than appended. This is to avoid
+ // directly leaking $random_state via the $output stream, which could
+ // allow for trivial prediction of further "random" numbers.
+ while (strlen($bytes) < $count) {
+ $random_state = hash('sha256', microtime() . mt_rand() . $random_state);
+ $bytes .= hash('sha256', mt_rand() . $random_state, true);
+ }
+ }
+ $output = substr($bytes, 0, $count);
+ $bytes = substr($bytes, $count);
+ return $output;
+ }
+
+ /**
+ * Generate a random string of specified length.
+ *
+ * Uses supplied character list for generating the new string.
+ * If no character list provided - uses Base64 URL character set.
+ *
+ * @param int $length Desired length of the string
+ * @param string|null $chars Characters to be chosen from randomly. If not given, the Base64 URL
+ * charset will be used.
+ *
+ * @return string The random string
+ *
+ * @throws InvalidArgumentException
+ *
+ * @copyright Copyright (c) 2005-2013 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license http://framework.zend.com/license/new-bsd New BSD License
+ *
+ * @see https://github.com/zendframework/zf2/blob/master/library/Zend/Math/Rand.php#L179
+ */
+ public static function getRandomString($length, $chars = null)
+ {
+ if ($length < 1) {
+ throw new InvalidArgumentException('Length should be >= 1');
+ }
+
+ if (empty($chars)) {
+ $numBytes = ceil($length * 0.75);
+ $bytes = self::getRandomBytes($numBytes);
+ $string = substr(rtrim(base64_encode($bytes), '='), 0, $length);
+
+ // Base64 URL
+ return strtr($string, '+/', '-_');
+ }
+
+ $listLen = strlen($chars);
+
+ if ($listLen == 1) {
+ return str_repeat($chars, $length);
+ }
+
+ $bytes = self::getRandomBytes($length);
+ $pos = 0;
+ $result = '';
+ for ($i = 0; $i < $length; $i++) {
+ $pos = ($pos + ord($bytes[$i])) % $listLen;
+ $result .= $chars[$pos];
+ }
+
+ return $result;
+ }
+}