PluginProbe ʕ •ᴥ•ʔ
JetBackup – Backup, Restore & Migrate / trunk
JetBackup – Backup, Restore & Migrate vtrunk
3.1.22.3 1.4.3 1.4.4 1.4.5 1.4.6 1.4.7 1.4.8 1.4.8.1 1.4.9 1.5.0 1.5.1 1.5.1.1 1.5.2 1.5.3 1.5.4 1.5.5 1.5.6 1.5.7 1.5.8 1.6.0 1.6.10 1.6.11 1.6.12 1.6.13 1.6.15 1.6.5.1 1.6.8.8 1.6.9 1.6.9.1 2.0.3 2.0.4 2.0.5 2.0.6 2.0.7.5 2.0.8.7 2.0.9.11 2.0.9.14 2.0.9.15 2.0.9.6 2.0.9.7 2.0.9.9 3.1.10.7 3.1.11.1 3.1.12.3 3.1.13.4 3.1.14.17 3.1.15.4 3.1.16.1 3.1.17.5 3.1.18.10 3.1.18.8 3.1.18.9 3.1.19.8 3.1.20.3 3.1.21.3 3.1.7.9 3.1.9.2 trunk 1.1.90 1.1.91 1.2.0 1.2.5 1.2.6 1.2.7 1.2.8 1.2.9 1.3.0 1.3.1 1.3.2 1.3.3 1.3.4 1.3.6 1.3.7 1.3.8 1.3.9 1.4.0 1.4.1 1.4.2
backup / src / JetBackup / 3rdparty / phpseclib3 / Crypt / Random.php
backup / src / JetBackup / 3rdparty / phpseclib3 / Crypt Last commit date
Common 1 year ago DH 1 year ago DSA 1 year ago EC 1 year ago RSA 1 year ago .htaccess 1 year ago AES.php 1 year ago Blowfish.php 1 year ago ChaCha20.php 1 year ago DES.php 1 year ago DH.php 1 year ago DSA.php 1 year ago EC.php 1 year ago Hash.php 1 year ago PublicKeyLoader.php 1 year ago RC2.php 1 year ago RC4.php 1 year ago RSA.php 1 year ago Random.php 1 year ago Rijndael.php 1 year ago Salsa20.php 1 year ago TripleDES.php 1 year ago Twofish.php 1 year ago index.html 1 year ago web.config 1 year ago
Random.php
223 lines
1 <?php
2
3 /**
4 * Random Number Generator
5 *
6 * PHP version 5
7 *
8 * Here's a short example of how to use this library:
9 * <code>
10 * <?php
11 * include 'vendor/autoload.php';
12 *
13 * echo bin2hex(\phpseclib3\Crypt\Random::string(8));
14 * ?>
15 * </code>
16 *
17 * @author Jim Wigginton <terrafrost@php.net>
18 * @copyright 2007 Jim Wigginton
19 * @license http://www.opensource.org/licenses/mit-license.html MIT License
20 * @link http://phpseclib.sourceforge.net
21 */
22
23 declare(strict_types=1);
24
25 namespace phpseclib3\Crypt;
26
27 use phpseclib3\Exception\RuntimeException;
28
29 /**
30 * Pure-PHP Random Number Generator
31 *
32 * @author Jim Wigginton <terrafrost@php.net>
33 */
34 abstract class Random
35 {
36 /**
37 * Generate a random string.
38 *
39 * Although microoptimizations are generally discouraged as they impair readability this function is ripe with
40 * microoptimizations because this function has the potential of being called a huge number of times.
41 * eg. for RSA key generation.
42 *
43 * @throws RuntimeException if a symmetric cipher is needed but not loaded
44 */
45 public static function string(int $length): string
46 {
47 if (!$length) {
48 return '';
49 }
50
51 try {
52 return random_bytes($length);
53 } catch (\Exception $e) {
54 // random_compat will throw an Exception, which in PHP 5 does not implement Throwable
55 } catch (\Throwable $e) {
56 // If a sufficient source of randomness is unavailable, random_bytes() will throw an
57 // object that implements the Throwable interface (Exception, TypeError, Error).
58 // We don't actually need to do anything here. The string() method should just continue
59 // as normal. Note, however, that if we don't have a sufficient source of randomness for
60 // random_bytes(), most of the other calls here will fail too, so we'll end up using
61 // the PHP implementation.
62 }
63 // at this point we have no choice but to use a pure-PHP CSPRNG
64
65 // cascade entropy across multiple PHP instances by fixing the session and collecting all
66 // environmental variables, including the previous session data and the current session
67 // data.
68 //
69 // mt_rand seeds itself by looking at the PID and the time, both of which are (relatively)
70 // easy to guess at. linux uses mouse clicks, keyboard timings, etc, as entropy sources, but
71 // PHP isn't low level to be able to use those as sources and on a web server there's not likely
72 // going to be a ton of keyboard or mouse action. web servers do have one thing that we can use
73 // however, a ton of people visiting the website. obviously you don't want to base your seeding
74 // solely on parameters a potential attacker sends but (1) not everything in $_SERVER is controlled
75 // by the user and (2) this isn't just looking at the data sent by the current user - it's based
76 // on the data sent by all users. one user requests the page and a hash of their info is saved.
77 // another user visits the page and the serialization of their data is utilized along with the
78 // server environment stuff and a hash of the previous http request data (which itself utilizes
79 // a hash of the session data before that). certainly an attacker should be assumed to have
80 // full control over his own http requests. he, however, is not going to have control over
81 // everyone's http requests.
82 static $crypto = false, $v;
83 if ($crypto === false) {
84 // save old session data
85 $old_session_id = session_id();
86 $old_use_cookies = ini_get('session.use_cookies');
87 $old_session_cache_limiter = session_cache_limiter();
88 $_OLD_SESSION = $_SESSION ?? false;
89 if ($old_session_id != '') {
90 session_write_close();
91 }
92
93 session_id(1);
94 ini_set('session.use_cookies', 0);
95 session_cache_limiter('');
96 session_start();
97
98 $v = (isset($_SERVER) ? self::safe_serialize($_SERVER) : '') .
99 (isset($_POST) ? self::safe_serialize($_POST) : '') .
100 (isset($_GET) ? self::safe_serialize($_GET) : '') .
101 (isset($_COOKIE) ? self::safe_serialize($_COOKIE) : '') .
102 // as of PHP 8.1 $GLOBALS can't be accessed by reference, which eliminates
103 // the need for phpseclib_safe_serialize. see https://wiki.php.net/rfc/restrict_globals_usage
104 // for more info
105 serialize($GLOBALS) .
106 self::safe_serialize($_SESSION) .
107 self::safe_serialize($_OLD_SESSION);
108 $v = $seed = $_SESSION['seed'] = sha1($v, true);
109 if (!isset($_SESSION['count'])) {
110 $_SESSION['count'] = 0;
111 }
112 $_SESSION['count']++;
113
114 session_write_close();
115
116 // restore old session data
117 if ($old_session_id != '') {
118 session_id($old_session_id);
119 session_start();
120 ini_set('session.use_cookies', $old_use_cookies);
121 session_cache_limiter($old_session_cache_limiter);
122 } else {
123 if ($_OLD_SESSION !== false) {
124 $_SESSION = $_OLD_SESSION;
125 unset($_OLD_SESSION);
126 } else {
127 unset($_SESSION);
128 }
129 }
130
131 // in SSH2 a shared secret and an exchange hash are generated through the key exchange process.
132 // the IV client to server is the hash of that "nonce" with the letter A and for the encryption key it's the letter C.
133 // if the hash doesn't produce enough a key or an IV that's long enough concat successive hashes of the
134 // original hash and the current hash. we'll be emulating that. for more info see the following URL:
135 //
136 // http://tools.ietf.org/html/rfc4253#section-7.2
137 //
138 // see the is_string($crypto) part for an example of how to expand the keys
139 $key = sha1($seed . 'A', true);
140 $iv = sha1($seed . 'C', true);
141
142 // ciphers are used as per the nist.gov link below. also, see this link:
143 //
144 // http://en.wikipedia.org/wiki/Cryptographically_secure_pseudorandom_number_generator#Designs_based_on_cryptographic_primitives
145 switch (true) {
146 case class_exists('\phpseclib3\Crypt\AES'):
147 $crypto = new AES('ctr');
148 break;
149 case class_exists('\phpseclib3\Crypt\Twofish'):
150 $crypto = new Twofish('ctr');
151 break;
152 case class_exists('\phpseclib3\Crypt\Blowfish'):
153 $crypto = new Blowfish('ctr');
154 break;
155 case class_exists('\phpseclib3\Crypt\TripleDES'):
156 $crypto = new TripleDES('ctr');
157 break;
158 case class_exists('\phpseclib3\Crypt\DES'):
159 $crypto = new DES('ctr');
160 break;
161 case class_exists('\phpseclib3\Crypt\RC4'):
162 $crypto = new RC4();
163 break;
164 default:
165 throw new RuntimeException(__CLASS__ . ' requires at least one symmetric cipher be loaded');
166 }
167
168 $crypto->setKey(substr($key, 0, $crypto->getKeyLength() >> 3));
169 $crypto->setIV(substr($iv, 0, $crypto->getBlockLength() >> 3));
170 $crypto->enableContinuousBuffer();
171 }
172
173 //return $crypto->encrypt(str_repeat("\0", $length));
174
175 // the following is based off of ANSI X9.31:
176 //
177 // http://csrc.nist.gov/groups/STM/cavp/documents/rng/931rngext.pdf
178 //
179 // OpenSSL uses that same standard for it's random numbers:
180 //
181 // http://www.opensource.apple.com/source/OpenSSL/OpenSSL-38/openssl/fips-1.0/rand/fips_rand.c
182 // (do a search for "ANS X9.31 A.2.4")
183 $result = '';
184 while (strlen($result) < $length) {
185 $i = $crypto->encrypt(microtime()); // strlen(microtime()) == 21
186 $r = $crypto->encrypt($i ^ $v); // strlen($v) == 20
187 $v = $crypto->encrypt($r ^ $i); // strlen($r) == 20
188 $result .= $r;
189 }
190
191 return substr($result, 0, $length);
192 }
193
194 /**
195 * Safely serialize variables
196 *
197 * If a class has a private __sleep() it'll emit a warning
198 */
199 private static function safe_serialize(&$arr): string
200 {
201 if (is_object($arr)) {
202 return '';
203 }
204 if (!is_array($arr)) {
205 return serialize($arr);
206 }
207 // prevent circular array recursion
208 if (isset($arr['__phpseclib_marker'])) {
209 return '';
210 }
211 $safearr = [];
212 $arr['__phpseclib_marker'] = true;
213 foreach (array_keys($arr) as $key) {
214 // do not recurse on the '__phpseclib_marker' key itself, for smaller memory usage
215 if ($key !== '__phpseclib_marker') {
216 $safearr[$key] = self::safe_serialize($arr[$key]);
217 }
218 }
219 unset($arr['__phpseclib_marker']);
220 return serialize($safearr);
221 }
222 }
223