diff --git includes/actions.inc includes/actions.inc
index 77734fe..56c94a4 100644
--- includes/actions.inc
+++ includes/actions.inc
@@ -197,7 +197,7 @@ function actions_get_all_actions() {
 }
 
 /**
- * Creates an associative array keyed by md5 hashes of function names or IDs.
+ * Creates an associative array keyed by hashes of function names or IDs.
  *
  * Hashes are used to prevent actual function names from going out into HTML
  * forms and coming back.
@@ -207,14 +207,14 @@ function actions_get_all_actions() {
  *   and associative arrays with keys 'label', 'type', etc. as values.
  *   This is usually the output of actions_list() or actions_get_all_actions().
  * @return
- *   An associative array whose keys are md5 hashes of the input array keys, and
+ *   An associative array whose keys are hashes of the input array keys, and
  *   whose corresponding values are associative arrays with components
  *   'callback', 'label', 'type', and 'configurable' from the input array.
  */
 function actions_actions_map($actions) {
   $actions_map = array();
   foreach ($actions as $callback => $array) {
-    $key = md5($callback);
+    $key = drupal_hash_base64($callback);
     $actions_map[$key]['callback']     = isset($array['callback']) ? $array['callback'] : $callback;
     $actions_map[$key]['label']        = $array['label'];
     $actions_map[$key]['type']         = $array['type'];
@@ -224,12 +224,12 @@ function actions_actions_map($actions) {
 }
 
 /**
- * Given an md5 hash of an action array key, returns the key (function or ID).
+ * Given a hash of an action array key, returns the key (function or ID).
  *
  * Faster than actions_actions_map() when you only need the function name or ID.
  *
  * @param $hash
- *   MD5 hash of a function name or action ID array key. The array key
+ *   Hash of a function name or action ID array key. The array key
  *   is a key into the return value of actions_list() (array key is the action
  *   function name) or actions_get_all_actions() (array key is the action ID).
  * @return
@@ -239,13 +239,20 @@ function actions_function_lookup($hash) {
   // Check for a function name match.
   $actions_list = actions_list();
   foreach ($actions_list as $function => $array) {
-    if (md5($function) == $hash) {
+    if (drupal_hash_base64($function) == $hash) {
       return $function;
     }
   }
-
+  $aid = FALSE;
   // Must be a configurable action; check database.
-  return db_query("SELECT aid FROM {actions} WHERE MD5(aid) = :hash AND parameters <> ''", array(':hash' => $hash))->fetchField();
+  $result = db_query("SELECT aid FROM {actions} WHERE parameters <> ''")->fetchAll(PDO::FETCH_ASSOC);
+  foreach ($result as $row) {
+    if (drupal_hash_base64($row['aid']) == $hash) {
+      $aid = $row['aid'];
+      break;
+    }
+  }
+  return $aid;
 }
 
 /**
diff --git includes/bootstrap.inc includes/bootstrap.inc
index 76f0fc7..985a511 100644
--- includes/bootstrap.inc
+++ includes/bootstrap.inc
@@ -1709,6 +1709,91 @@ function drupal_block_denied($ip) {
 }
 
 /**
+ * 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;
+  // 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) {
+    // /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);
+    }
+    // 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;
+}
+
+/**
+ * Calculate a base-64 encoded, URL-safe sha-256 hmac.
+ *
+ * @param $data
+ *   String to be validated with the hmac.
+ * @param $key
+ *   A secret string key.
+ *
+ * @return
+ *   A base-64 encoded sha-256 hmac, with + replaced with -, / with _ and
+ *   any = padding characters removed.
+ */
+function drupal_hmac_base64($data, $key) {
+  $hmac = base64_encode(hash_hmac('sha256', $data, $key, TRUE));
+  // Modify the hmac so it's safe to use in URLs.
+  return strtr($hmac, array('+' => '-', '/' => '_', '=' => ''));
+}
+
+/**
+ * Calculate a base-64 encoded, URL-safe sha-256 hash.
+ *
+ * @param $data
+ *   String to be hashed.
+ *
+ * @return
+ *   A base-64 encoded sha-256 hash, with + replaced with -, / with _ and
+ *   any = padding characters removed.
+ */
+function drupal_hash_base64($data) {
+  $hash = base64_encode(hash('sha256', $data, TRUE));
+  // Modify the hash so it's safe to use in URLs.
+  return strtr($hash, array('+' => '-', '/' => '_', '=' => ''));
+}
+
+/**
  * Generates a default anonymous $user object.
  *
  * @return Object - the user object.
@@ -2008,7 +2093,7 @@ function drupal_valid_test_ua($user_agent) {
   $filepath = DRUPAL_ROOT . '/includes/bootstrap.inc';
   $key = sha1(serialize($databases) . filectime($filepath) . fileinode($filepath), TRUE);
   // The HMAC must match.
-  return $hmac == base64_encode(hash_hmac('sha1', $check_string, $key, TRUE));
+  return $hmac == drupal_hmac_base64($check_string, $key);
 }
 
 /**
@@ -2028,7 +2113,7 @@ function drupal_generate_test_ua($prefix) {
    // Generate a moderately secure HMAC based on the database credentials.
    $salt = uniqid('', TRUE);
    $check_string = $prefix . ';' . time() . ';' . $salt;
-   return  $check_string . ';' . base64_encode(hash_hmac('sha1', $check_string, $key, TRUE));
+   return  $check_string . ';' . drupal_hmac_base64($check_string, $key);
 }
 
 /**
diff --git includes/common.inc includes/common.inc
index 3fcda62..ec6e236 100644
--- includes/common.inc
+++ includes/common.inc
@@ -2883,7 +2883,7 @@ function drupal_aggregate_css(&$css_groups) {
         if ($group['preprocess'] && $preprocess_css) {
           // Prefix filename to prevent blocking by firewalls which reject files
           // starting with "ad*".
-          $filename = 'css_' . md5(serialize($group['items'])) . '.css';
+          $filename = 'css_' . drupal_hash_base64(serialize($group['items'])) . '.css';
           $css_groups[$key]['data'] = drupal_build_css_cache($group['items'], $filename);
         }
         break;
@@ -3694,7 +3694,7 @@ function drupal_get_js($scope = 'header', $javascript = NULL) {
     // Prefix filename to prevent blocking by firewalls which reject files
     // starting with "ad*".
     foreach ($files as $key => $file_set) {
-      $filename = 'js_' . md5(serialize($file_set)) . '.js';
+      $filename = 'js_' . drupal_hash_base64(serialize($file_set)) . '.js';
       $uri = drupal_build_js_cache($file_set, $filename);
       // Only include the file if was written successfully. Errors are logged
       // using watchdog.
@@ -4180,45 +4180,6 @@ function drupal_json_output($var = NULL) {
 }
 
 /**
- * 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;
-  // We initialize with the somewhat random PHP process ID on the first call.
-  if (empty($random_state)) {
-    $random_state = getmypid();
-  }
-  $output = '';
-  // /dev/urandom is available on many *nix systems and is considered the best
-  // commonly available pseudo-random source.
-  if ($fh = @fopen('/dev/urandom', 'rb')) {
-    $output = fread($fh, $count);
-    fclose($fh);
-  }
-  // 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 md5() prior to being rolled into $output, that the two md5()
-  // 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($output) < $count) {
-    $random_state = md5(microtime() . mt_rand() . $random_state);
-    $output .= md5(mt_rand() . $random_state, TRUE);
-  }
-  return substr($output, 0, $count);
-}
-
-/**
  * Get a salt useful for hardening against SQL injection.
  *
  * @return
@@ -4228,7 +4189,7 @@ function drupal_get_hash_salt() {
   global $drupal_hash_salt, $databases;
   // If the $drupal_hash_salt variable is empty, a hash of the serialized
   // database credentials is used as a fallback salt.
-  return empty($drupal_hash_salt) ? sha1(serialize($databases)) : $drupal_hash_salt;
+  return empty($drupal_hash_salt) ? drupal_hash_base64(serialize($databases)) : $drupal_hash_salt;
 }
 
 /**
@@ -4239,7 +4200,7 @@ function drupal_get_hash_salt() {
  */
 function drupal_get_private_key() {
   if (!($key = variable_get('drupal_private_key', 0))) {
-    $key = md5(drupal_random_bytes(64));
+    $key = drupal_hash_base64(drupal_random_bytes(64));
     variable_set('drupal_private_key', $key);
   }
   return $key;
@@ -4252,10 +4213,7 @@ function drupal_get_private_key() {
  *   An additional value to base the token on.
  */
 function drupal_get_token($value = '') {
-  $private_key = drupal_get_private_key();
-  // A single md5() is vulnerable to length-extension attacks, so use it twice.
-  // @todo:  add md5 and sha1 hmac functions to core.
-  return md5(drupal_get_hash_salt() . md5(session_id() . $value . $private_key));
+  return drupal_hmac_base64($value, session_id() . drupal_get_private_key() . drupal_get_hash_salt());
 }
 
 /**
@@ -5139,7 +5097,7 @@ function drupal_render_cache_set(&$markup, $elements) {
 function drupal_render_cache_by_query($query, $function, $expire = CACHE_TEMPORARY, $granularity = NULL) {
   $cache_keys = array_merge(array($function), drupal_render_cid_parts($granularity));
   $query->preExecute();
-  $cache_keys[] = md5(serialize(array((string) $query, $query->getArguments())));
+  $cache_keys[] = drupal_hash_base64(serialize(array((string) $query, $query->getArguments())));
   return array(
     '#query' => $query,
     '#pre_render' => array($function . '_pre_render'),
diff --git includes/form.inc includes/form.inc
index 2c6e61f..1388e6f 100644
--- includes/form.inc
+++ includes/form.inc
@@ -203,7 +203,7 @@ function drupal_build_form($form_id, &$form_state) {
       }
 
       $form = drupal_retrieve_form($form_id, $form_state);
-      $form_build_id = 'form-' . md5(uniqid(mt_rand(), TRUE));
+      $form_build_id = 'form-' . drupal_hash_base64(uniqid(mt_rand(), TRUE) . mt_rand());
       $form['#build_id'] = $form_build_id;
 
       // Fix the form method, if it is 'get' in $form_state, but not in $form.
@@ -331,7 +331,7 @@ function drupal_rebuild_form($form_id, &$form_state, $old_form = NULL) {
   // Otherwise, a new #build_id is generated, to not clobber the previous
   // build's data in the form cache; also allowing the user to go back to an
   // earlier build, make changes, and re-submit.
-  $form['#build_id'] = isset($old_form['#build_id']) ? $old_form['#build_id'] : 'form-' . md5(mt_rand());
+  $form['#build_id'] = isset($old_form['#build_id']) ? $old_form['#build_id'] : 'form-' . drupal_hash_base64(uniqid(mt_rand(), TRUE) . mt_rand());
 
   // #action defaults to request_uri(), but in case of AJAX and other partial
   // rebuilds, the form is submitted to an alternate URL, and the original
diff --git includes/install.core.inc includes/install.core.inc
index c0715e2..77a4a1c 100644
--- includes/install.core.inc
+++ includes/install.core.inc
@@ -1004,7 +1004,7 @@ function install_settings_form_submit($form, &$form_state) {
     'required' => TRUE,
   );
   $settings['drupal_hash_salt'] = array(
-    'value'    => sha1(drupal_random_bytes(64)),
+    'value'    => drupal_hash_base64(drupal_random_bytes(64)),
     'required' => TRUE,
   );
   drupal_rewrite_settings($settings);
diff --git includes/menu.inc includes/menu.inc
index 3c355ce..063dbf9 100644
--- includes/menu.inc
+++ includes/menu.inc
@@ -408,8 +408,8 @@ function menu_get_item($path = NULL, $router_item = NULL) {
     $ancestors = menu_get_ancestors($parts);
 
     // Since there is no limit to the length of $path, but the cids are
-    // restricted to 255 characters, use md5() to keep it short yet unique.
-    $cid = 'menu_item:' . md5($path);
+    // restricted to 255 characters, use sha256 to keep it short yet unique.
+    $cid = 'menu_item:' . drupal_hash_base64($path);
     if ($cached = cache_get($cid, 'cache_menu')) {
       $router_item = $cached->data;
     }
@@ -1238,7 +1238,7 @@ function menu_tree_page_data($menu_name, $max_depth = NULL) {
  * Helper function - compute the real cache ID for menu tree data.
  */
 function _menu_tree_cid($menu_name, $data) {
-  return 'links:' . $menu_name . ':tree-data:' . $GLOBALS['language']->language . ':' . md5(serialize($data));
+  return 'links:' . $menu_name . ':tree-data:' . $GLOBALS['language']->language . ':' . drupal_hash_base64(serialize($data));
 }
 
 /**
diff --git includes/session.inc includes/session.inc
index 438d47d..774e272 100644
--- includes/session.inc
+++ includes/session.inc
@@ -206,7 +206,10 @@ function drupal_session_initialize() {
     // processes (like drupal_get_token()) needs to know the future
     // session ID in advance.
     $user = drupal_anonymous_user();
-    session_id(md5(uniqid('', TRUE)));
+    // Less random sessions (which are much faster to generate) are used for
+    // anonymous users than are generated in drupal_session_regenerate() when
+    // a user becomes authenticated.
+    session_id(drupal_hash_base64(uniqid(mt_rand(), TRUE)));
   }
 }
 
@@ -283,7 +286,7 @@ function drupal_session_regenerate() {
   if ($is_https && variable_get('https', FALSE)) {
     $insecure_session_name = substr(session_name(), 1);
     $params = session_get_cookie_params();
-    $session_id = md5(uniqid(mt_rand(), TRUE));
+    $session_id = drupal_hash_base64(uniqid(mt_rand(), TRUE) . drupal_random_bytes(55));
     setcookie($insecure_session_name, $session_id, REQUEST_TIME + $params['lifetime'], $params['path'], $params['domain'], FALSE, $params['httponly']);
     $_COOKIE[$insecure_session_name] = $session_id;
   }
diff --git modules/book/book.admin.inc modules/book/book.admin.inc
index 8ed7216..771c9df 100644
--- modules/book/book.admin.inc
+++ modules/book/book.admin.inc
@@ -154,7 +154,7 @@ function _book_admin_table($node, &$form) {
   $tree = book_menu_subtree_data($node->book);
   $tree = array_shift($tree); // Do not include the book item itself.
   if ($tree['below']) {
-    $hash = sha1(serialize($tree['below']));
+    $hash = drupal_hash_base64(serialize($tree['below']));
     // Store the hash value as a hidden form element so that we can detect
     // if another user changed the book hierarchy.
     $form['tree_hash'] = array(
diff --git modules/book/book.module modules/book/book.module
index d60ab18..b99cf57 100644
--- modules/book/book.module
+++ modules/book/book.module
@@ -1246,7 +1246,7 @@ function book_menu_subtree_data($link) {
       $data['node_links'] = array();
       menu_tree_collect_node_links($data['tree'], $data['node_links']);
       // Compute the real cid for book subtree data.
-      $tree_cid = 'links:' . $item['menu_name'] . ':subtree-data:' . md5(serialize($data));
+      $tree_cid = 'links:' . $item['menu_name'] . ':subtree-data:' . drupal_hash_base64(serialize($data));
       // Cache the data, if it is not already in the cache.
 
       if (!cache_get($tree_cid, 'cache_menu')) {
diff --git modules/simpletest/tests/actions.test modules/simpletest/tests/actions.test
index 3a098a8..c673d94 100644
--- modules/simpletest/tests/actions.test
+++ modules/simpletest/tests/actions.test
@@ -21,7 +21,7 @@ class ActionsConfigurationTestCase extends DrupalWebTestCase {
 
     // Make a POST request to admin/config/system/actions/manage.
     $edit = array();
-    $edit['action'] = md5('system_goto_action');
+    $edit['action'] = drupal_hash_base64('system_goto_action');
     $this->drupalPost('admin/config/system/actions/manage', $edit, t('Create'));
 
     // Make a POST request to the individual action configuration page.
@@ -29,7 +29,7 @@ class ActionsConfigurationTestCase extends DrupalWebTestCase {
     $action_label = $this->randomName();
     $edit['actions_label'] = $action_label;
     $edit['url'] = 'admin';
-    $this->drupalPost('admin/config/system/actions/configure/' . md5('system_goto_action'), $edit, t('Save'));
+    $this->drupalPost('admin/config/system/actions/configure/' . drupal_hash_base64('system_goto_action'), $edit, t('Save'));
 
     // Make sure that the new complex action was saved properly.
     $this->assertText(t('The action has been successfully saved.'), t("Make sure we get a confirmation that we've successfully saved the complex action."));
@@ -87,7 +87,7 @@ class ActionLoopTestCase extends DrupalWebTestCase {
     $user = $this->drupalCreateUser(array('administer actions'));
     $this->drupalLogin($user);
 
-    $hash = md5('actions_loop_test_log');
+    $hash = drupal_hash_base64('actions_loop_test_log');
     $edit = array('aid' => $hash);
     $this->drupalPost('admin/structure/trigger/actions_loop_test', $edit, t('Assign'));
 
diff --git modules/system/system.admin.inc modules/system/system.admin.inc
index e0fcabb..32d6337 100644
--- modules/system/system.admin.inc
+++ modules/system/system.admin.inc
@@ -2935,7 +2935,7 @@ function system_actions_manage_form_submit($form, &$form_state) {
  * on our elements.
  *
  * @param $action
- *   md5 hash of an action ID or an integer. If it is an md5 hash, we are
+ *   Hash of an action ID or an integer. If it is a hash, we are
  *   creating a new instance. If it is an integer, we are editing an existing
  *   instance.
  * @return
@@ -2960,7 +2960,7 @@ function system_actions_configure($form, &$form_state, $action = NULL) {
     $edit['actions_label'] = $data->label;
     $edit['actions_type'] = $data->type;
     $function = $data->callback;
-    $action = md5($data->callback);
+    $action = drupal_hash_base64($data->callback);
     $params = unserialize($data->parameters);
     if ($params) {
       foreach ($params as $name => $val) {
diff --git modules/system/system.install modules/system/system.install
index 5e3804b..11d068e 100644
--- modules/system/system.install
+++ modules/system/system.install
@@ -414,7 +414,7 @@ function system_install() {
     ->execute();
 
   // Populate the cron key variable.
-  $cron_key = md5(mt_rand());
+  $cron_key = drupal_hash_base64(drupal_random_bytes(55));
   variable_set('cron_key', $cron_key);
 }
 
@@ -1650,7 +1650,7 @@ function system_update_7000() {
  * Generate a cron key and save it in the variables table.
  */
 function system_update_7001() {
-  variable_set('cron_key', md5(mt_rand()));
+  variable_set('cron_key', drupal_hash_base64(drupal_random_bytes(55)));
 }
 
 /**
diff --git modules/trigger/trigger.admin.inc modules/trigger/trigger.admin.inc
index 1b68567..0f23dcb 100644
--- modules/trigger/trigger.admin.inc
+++ modules/trigger/trigger.admin.inc
@@ -155,10 +155,11 @@ function trigger_assign_form($form, $form_state, $module, $hook, $label) {
   foreach ($actions as $aid => $info) {
     // If action is defined unassign it, otherwise offer to delete all orphaned
     // actions.
-    if (actions_function_lookup(md5($aid))) {
+    $hash = drupal_hash_base64($aid, TRUE);
+    if (actions_function_lookup($hash)) {
       $form[$hook]['assigned']['#value'][$aid] = array(
         'label' => $info['label'],
-        'link' => l(t('unassign'), "admin/structure/trigger/unassign/$module/$hook/" . md5($aid)),
+        'link' => l(t('unassign'), "admin/structure/trigger/unassign/$module/$hook/$hash"),
       );
     }
     else {
diff --git modules/trigger/trigger.test modules/trigger/trigger.test
index c62e983..22533b3 100644
--- modules/trigger/trigger.test
+++ modules/trigger/trigger.test
@@ -19,7 +19,7 @@ class TriggerWebTestCase extends DrupalWebTestCase {
    */
   protected function configureAdvancedAction($action, $edit) {
     // Create an advanced action.
-    $hash = md5($action);
+    $hash = drupal_hash_base64($action);
     $this->drupalPost("admin/config/system/actions/configure/$hash", $edit, t('Save'));
     $this->assertText(t('The action has been successfully saved.'));
 
@@ -58,7 +58,7 @@ class TriggerContentTestCase extends TriggerWebTestCase {
     $test_user = $this->drupalCreateUser(array('administer actions'));
     $web_user = $this->drupalCreateUser(array('create page content', 'access content', 'administer nodes'));
     foreach ($content_actions as $action) {
-      $hash = md5($action);
+      $hash = drupal_hash_base64($action);
       $info = $this->actionInfo($action);
 
       // Assign an action to a trigger, then pull the trigger, and make sure
@@ -112,7 +112,7 @@ class TriggerContentTestCase extends TriggerWebTestCase {
     }
 
     $action_id = 'trigger_test_generic_any_action';
-    $hash = md5($action_id);
+    $hash = drupal_hash_base64($action_id);
     $edit = array('aid' => $hash);
     $this->drupalPost('admin/structure/trigger/node', $edit, t('Assign'));
 
@@ -199,7 +199,7 @@ class TriggerCronTestCase extends TriggerWebTestCase {
     $this->drupalLogin($test_user);
 
     // Assign a non-configurable action to the cron run trigger.
-    $edit = array('aid' => md5('trigger_test_system_cron_action'));
+    $edit = array('aid' => drupal_hash_base64('trigger_test_system_cron_action'));
     $this->drupalPost('admin/structure/trigger/system', $edit, t('Assign'), array(), array(), 'trigger-cron-assign-form');
 
     // Assign a configurable action to the cron trigger.
@@ -211,7 +211,7 @@ class TriggerCronTestCase extends TriggerWebTestCase {
     $aid = $this->configureAdvancedAction('trigger_test_system_cron_conf_action', $edit);
     // $aid is likely 3 but if we add more uses for the sequences table in
     // core it might break, so it is easier to get the value from the database.
-    $edit = array('aid' => md5($aid));
+    $edit = array('aid' => drupal_hash_base64($aid));
     $this->drupalPost('admin/structure/trigger/system', $edit, t('Assign'), array(), array(), 'trigger-cron-assign-form');
 
     // Add a second configurable action to the cron trigger.
@@ -221,7 +221,7 @@ class TriggerCronTestCase extends TriggerWebTestCase {
       'subject' => $action_label,
     );
     $aid = $this->configureAdvancedAction('trigger_test_system_cron_conf_action', $edit);
-    $edit = array('aid' => md5($aid));
+    $edit = array('aid' => drupal_hash_base64($aid));
     $this->drupalPost('admin/structure/trigger/system', $edit, t('Assign'), array(), array(), 'trigger-cron-assign-form');
 
     // Force a cron run.
@@ -264,7 +264,7 @@ class TriggerOtherTestCase extends TriggerWebTestCase {
     $test_user = $this->drupalCreateUser(array('administer actions'));
     $this->drupalLogin($test_user);
     $action_id = 'trigger_test_generic_action';
-    $hash = md5($action_id);
+    $hash = drupal_hash_base64($action_id);
     $edit = array('aid' => $hash);
     $this->drupalPost('admin/structure/trigger/user', $edit, t('Assign'), array(), array(), 'trigger-user-insert-assign-form');
 
@@ -299,7 +299,7 @@ class TriggerOtherTestCase extends TriggerWebTestCase {
 
     // Configure an advanced action that we can assign.
     $aid = $this->configureAdvancedAction('system_message_action', $action_edit);
-    $edit = array('aid' => md5($aid));
+    $edit = array('aid' => drupal_hash_base64($aid));
     $this->drupalPost('admin/structure/trigger/user', $edit, t('Assign'), array(), array(), 'trigger-user-login-assign-form');
 
     // Verify that the action has been assigned to the correct hook.
@@ -321,7 +321,7 @@ class TriggerOtherTestCase extends TriggerWebTestCase {
     $test_user = $this->drupalCreateUser(array('administer actions'));
     $this->drupalLogin($test_user);
     $action_id = 'trigger_test_generic_action';
-    $hash = md5($action_id);
+    $hash = drupal_hash_base64($action_id);
     $edit = array('aid' => $hash);
     $this->drupalPost('admin/structure/trigger/comment', $edit, t('Assign'), array(), array(), 'trigger-comment-insert-assign-form');
 
@@ -350,7 +350,7 @@ class TriggerOtherTestCase extends TriggerWebTestCase {
     $test_user = $this->drupalCreateUser(array('administer actions'));
     $this->drupalLogin($test_user);
     $action_id = 'trigger_test_generic_action';
-    $hash = md5($action_id);
+    $hash = drupal_hash_base64($action_id);
     $edit = array('aid' => $hash);
     $this->drupalPost('admin/structure/trigger/taxonomy', $edit, t('Assign'), array(), array(), 'trigger-taxonomy-term-insert-assign-form');
 
@@ -402,7 +402,7 @@ class TriggerOrphanedActionsTestCase extends DrupalWebTestCase {
    */
   function testActionsOrphaned() {
     $action = 'trigger_test_generic_any_action';
-    $hash = md5($action);
+    $hash = drupal_hash_base64($action);
 
     // Assign an action from a disable-able module to a trigger, then pull the
     // trigger, and make sure the actions fire.
diff --git modules/update/update.fetch.inc modules/update/update.fetch.inc
index 7944828..9db4d1c 100644
--- modules/update/update.fetch.inc
+++ modules/update/update.fetch.inc
@@ -137,7 +137,7 @@ function _update_process_fetch_task($project) {
 
   $success = FALSE;
   $available = array();
-  $site_key = md5($base_url . drupal_get_private_key());
+  $site_key = drupal_hmac_base64($base_url, drupal_get_private_key());
   $url = _update_build_fetch_url($project, $site_key);
   $fetch_url_base = _update_get_fetch_url_base($project);
   $project_name = $project['name'];
diff --git modules/user/user.module modules/user/user.module
index 1dfcf35..ec45014 100644
--- modules/user/user.module
+++ modules/user/user.module
@@ -2079,8 +2079,7 @@ function user_cancel_url($account) {
 }
 
 function user_pass_rehash($password, $timestamp, $login) {
-  // A single md5() is vulnerable to length-extension attacks, so use it twice.
-  return md5(drupal_get_hash_salt() . md5($timestamp . $password . $login));
+  return drupal_hmac_base64($timestamp . $login, drupal_get_hash_salt() . $password);
 }
 
 /**
diff --git modules/user/user.pages.inc modules/user/user.pages.inc
index db70017..cd9134c 100644
--- modules/user/user.pages.inc
+++ modules/user/user.pages.inc
@@ -133,7 +133,7 @@ function user_pass_reset($form, &$form_state, $uid, $timestamp, $hashed_pass, $a
           user_login_finalize();
           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 = md5(drupal_random_bytes(55));
+          $token = drupal_hash_base64(drupal_random_bytes(55));
           $_SESSION['pass_reset_' . $user->uid] = $token;
           drupal_goto('user/' . $user->uid . '/edit', array('query' => array('pass-reset-token' => $token)));
         }
