diff --git a/core/includes/bootstrap.inc b/core/includes/bootstrap.inc
index c14ab53..7e72009 100644
--- a/core/includes/bootstrap.inc
+++ b/core/includes/bootstrap.inc
@@ -1903,68 +1903,6 @@ function drupal_set_title($title = NULL, $output = CHECK_PLAIN) {
 }
 
 /**
- * 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 $count
- *   The number of characters (bytes) to return in the string.
- */
-function drupal_random_bytes($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);
-    }
-    // openssl_random_pseudo_bytes() will find entropy in a system-dependent
-    // way.
-    elseif ($php_compatible && function_exists('openssl_random_pseudo_bytes')) {
-      $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;
-}
-
-/**
  * Calculates a base-64 encoded, URL-safe sha-256 hmac.
  *
  * @param $data
diff --git a/core/includes/common.inc b/core/includes/common.inc
index 35056de..3975271 100644
--- a/core/includes/common.inc
+++ b/core/includes/common.inc
@@ -7,6 +7,7 @@
 use Symfony\Component\Yaml\Parser;
 use Drupal\Component\PhpStorage\PhpStorageFactory;
 use Drupal\Component\Utility\NestedArray;
+use Drupal\Component\Utility\RandomBytes;
 use Drupal\Core\Cache\CacheBackendInterface;
 use Drupal\Core\Datetime\DrupalDateTime;
 use Drupal\Core\Database\Database;
@@ -4855,7 +4856,7 @@ function drupal_get_hash_salt() {
  */
 function drupal_get_private_key() {
   if (!($key = state()->get('system.private_key'))) {
-    $key = drupal_hash_base64(drupal_random_bytes(55));
+    $key = drupal_hash_base64(RandomBytes::generate(55));
     state()->set('system.private_key', $key);
   }
   return $key;
diff --git a/core/includes/install.core.inc b/core/includes/install.core.inc
index df688ab..153feaf 100644
--- a/core/includes/install.core.inc
+++ b/core/includes/install.core.inc
@@ -5,6 +5,7 @@
 use Drupal\Core\Database\Database;
 use Drupal\Core\Database\Install\TaskException;
 use Drupal\Core\Language\Language;
+use Drupal\Component\Utility\RandomBytes;
 
 use Symfony\Component\DependencyInjection\ContainerBuilder;
 use Symfony\Component\DependencyInjection\Reference;
@@ -1123,7 +1124,7 @@ function install_settings_form_submit($form, &$form_state) {
     'required' => TRUE,
   );
   $settings['drupal_hash_salt'] = (object) array(
-    'value'    => drupal_hash_base64(drupal_random_bytes(55)),
+    'value'    => drupal_hash_base64(RandomBytes::generate(55)),
     'required' => TRUE,
   );
 
diff --git a/core/includes/install.inc b/core/includes/install.inc
index 391750f..d7022f0 100644
--- a/core/includes/install.inc
+++ b/core/includes/install.inc
@@ -5,6 +5,7 @@
  * API functions for installing modules and themes.
  */
 
+use Drupal\Component\Utility\RandomBytes;
 use Drupal\Core\Database\Database;
 use Drupal\Core\DrupalKernel;
 use Drupal\locale\Gettext;
@@ -445,7 +446,7 @@ function drupal_install_config_directories() {
   // Add a randomized config directory name to settings.php, unless it was
   // manually defined in the existing already.
   if (empty($config_directories)) {
-    $config_directories_hash = drupal_hash_base64(drupal_random_bytes(55));
+    $config_directories_hash = drupal_hash_base64(RandomBytes::generate(55));
     $settings['config_directories'] = array(
       CONFIG_ACTIVE_DIRECTORY => array(
         'path' => (object) array(
diff --git a/core/includes/session.inc b/core/includes/session.inc
index 31e67a6..8344dc9 100644
--- a/core/includes/session.inc
+++ b/core/includes/session.inc
@@ -16,6 +16,8 @@
  * data should instead be accessed via the $_SESSION superglobal.
  */
 
+use Drupal\Component\Utility\RandomBytes;
+
 /**
  * Session handler assigned by session_set_save_handler().
  *
@@ -357,7 +359,7 @@ function drupal_session_regenerate() {
       $old_insecure_session_id = $_COOKIE[$insecure_session_name];
     }
     $params = session_get_cookie_params();
-    $session_id = drupal_hash_base64(uniqid(mt_rand(), TRUE) . drupal_random_bytes(55));
+    $session_id = drupal_hash_base64(uniqid(mt_rand(), TRUE) . RandomBytes::generate(55));
     // If a session cookie lifetime is set, the session will expire
     // $params['lifetime'] seconds from the current request. If it is not set,
     // it will expire when the browser is closed.
@@ -369,7 +371,7 @@ function drupal_session_regenerate() {
   if (drupal_session_started()) {
     $old_session_id = session_id();
   }
-  session_id(drupal_hash_base64(uniqid(mt_rand(), TRUE) . drupal_random_bytes(55)));
+  session_id(drupal_hash_base64(uniqid(mt_rand(), TRUE) . RandomBytes::generate(55)));
 
   if (isset($old_session_id)) {
     $params = session_get_cookie_params();
diff --git a/core/lib/Drupal/Component/Utility/RandomBytes.php b/core/lib/Drupal/Component/Utility/RandomBytes.php
new file mode 100644
index 0000000..4519fc1
--- /dev/null
+++ b/core/lib/Drupal/Component/Utility/RandomBytes.php
@@ -0,0 +1,75 @@
+<?php
+
+/**
+ * @file
+ * Definition of Drupal\Component\Utility\RandomBytes.
+ */
+
+namespace Drupal\Component\Utility;
+
+/**
+ * Generates randomized bytes.
+ */
+class RandomBytes {
+
+  /**
+   * 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 $count
+   *   The number of characters (bytes) to return in the string.
+   */
+  public static function generate($count) {
+    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);
+      }
+      // openssl_random_pseudo_bytes() will find entropy in a system-dependent
+      // way.
+      elseif ($php_compatible && function_exists('openssl_random_pseudo_bytes')) {
+        $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;
+  }
+}
diff --git a/core/lib/Drupal/Component/Uuid/Php.php b/core/lib/Drupal/Component/Uuid/Php.php
index fd12fc0..9016a9b 100644
--- a/core/lib/Drupal/Component/Uuid/Php.php
+++ b/core/lib/Drupal/Component/Uuid/Php.php
@@ -7,6 +7,8 @@
 
 namespace Drupal\Component\Uuid;
 
+use Drupal\Component\Utility\RandomBytes;
+
 /**
  * Generates a UUID v4 using PHP code.
  *
@@ -20,7 +22,7 @@ class Php implements UuidInterface {
    * Implements Drupal\Component\Uuid\UuidInterface::generate().
    */
   public function generate() {
-    $hex = substr(hash('sha256', drupal_random_bytes(16)), 0, 32);
+    $hex = substr(hash('sha256', RandomBytes::generate(16)), 0, 32);
 
     // The field names refer to RFC 4122 section 4.1.2.
     $time_low = substr($hex, 0, 8);
diff --git a/core/lib/Drupal/Core/Password/PhpassHashedPassword.php b/core/lib/Drupal/Core/Password/PhpassHashedPassword.php
index 157e14c..a06d678 100644
--- a/core/lib/Drupal/Core/Password/PhpassHashedPassword.php
+++ b/core/lib/Drupal/Core/Password/PhpassHashedPassword.php
@@ -7,6 +7,8 @@
 
 namespace Drupal\Core\Password;
 
+use Drupal\Component\Utility\RandomBytes;
+
 /**
  * Secure password hashing functions based on the Portable PHP password
  * hashing framework.
@@ -109,7 +111,7 @@ protected function generateSalt() {
     // We encode the final log2 iteration count in base 64.
     $output .= static::$ITOA64[$this->countLog2];
     // 6 bytes is the standard salt for a portable phpass hash.
-    $output .= $this->base64Encode(drupal_random_bytes(6), 6);
+    $output .= $this->base64Encode(RandomBytes::generate(6), 6);
     return $output;
   }
 
diff --git a/core/modules/system/lib/Drupal/system/Tests/Upgrade/UpgradePathTestBase.php b/core/modules/system/lib/Drupal/system/Tests/Upgrade/UpgradePathTestBase.php
index 74c9923..5142c11 100644
--- a/core/modules/system/lib/Drupal/system/Tests/Upgrade/UpgradePathTestBase.php
+++ b/core/modules/system/lib/Drupal/system/Tests/Upgrade/UpgradePathTestBase.php
@@ -7,6 +7,7 @@
 
 namespace Drupal\system\Tests\Upgrade;
 
+use Drupal\Component\Utility\RandomBytes;
 use Drupal\Core\Database\Database;
 use Drupal\simpletest\WebTestBase;
 use Exception;
@@ -45,7 +46,7 @@
   protected function prepareD8Session() {
     // Generate and set a D7-compatible session cookie.
     $this->curlInitialize();
-    $sid = drupal_hash_base64(uniqid(mt_rand(), TRUE) . drupal_random_bytes(55));
+    $sid = drupal_hash_base64(uniqid(mt_rand(), TRUE) . RandomBytes::generate(55));
     curl_setopt($this->curlHandle, CURLOPT_COOKIE, rawurlencode(session_name()) . '=' . rawurlencode($sid));
 
     // Force our way into the session of the child site.
diff --git a/core/modules/system/system.install b/core/modules/system/system.install
index a93a124..32bd764 100644
--- a/core/modules/system/system.install
+++ b/core/modules/system/system.install
@@ -1,5 +1,6 @@
 <?php
 
+use Drupal\Component\Utility\RandomBytes;
 use Drupal\Core\Database\Database;
 
 /**
@@ -529,7 +530,7 @@ function system_install() {
     ->save();
 
   // Populate the cron key state variable.
-  $cron_key = drupal_hash_base64(drupal_random_bytes(55));
+  $cron_key = drupal_hash_base64(RandomBytes::generate(55));
   state()->set('system.cron_key', $cron_key);
 }
 
diff --git a/core/modules/user/user.pages.inc b/core/modules/user/user.pages.inc
index 140b767..999d0d1 100644
--- a/core/modules/user/user.pages.inc
+++ b/core/modules/user/user.pages.inc
@@ -10,6 +10,7 @@
 use Symfony\Component\HttpFoundation\RedirectResponse;
 use Symfony\Component\HttpKernel\Exception\AccessDeniedHttpException;
 use Symfony\Component\HttpKernel\HttpKernelInterface;
+use Drupal\Component\Utility\RandomBytes;
 
 /**
  * Form builder; Request a password reset.
@@ -126,7 +127,7 @@ function user_pass_reset($form, &$form_state, $uid, $timestamp, $hashed_pass, $a
           watchdog('user', 'User %name used one-time login link at time %timestamp.', array('%name' => $account->name, '%timestamp' => $timestamp));
           drupal_set_message(t('You have just used your one-time login link. It is no longer necessary to use this link to log in. Please change your password.'));
           // Let the user's password be changed without the current password check.
-          $token = drupal_hash_base64(drupal_random_bytes(55));
+          $token = drupal_hash_base64(RandomBytes::generate(55));
           $_SESSION['pass_reset_' . $user->uid] = $token;
           drupal_goto('user/' . $user->uid . '/edit', array('query' => array('pass-reset-token' => $token)));
         }
