diff --git a/core/composer.json b/core/composer.json
index c975dc9..067f70c 100644
--- a/core/composer.json
+++ b/core/composer.json
@@ -31,7 +31,8 @@
     "behat/mink": "~1.6",
     "behat/mink-goutte-driver": "~1.1",
     "fabpot/goutte": "^2.0.3",
-    "masterminds/html5": "~2.1"
+    "masterminds/html5": "~2.1",
+    "ircmaxell/password-compat": "~1.0"
   },
   "autoload": {
     "psr-4": {
diff --git a/core/composer.lock b/core/composer.lock
index 0c90697..25db4e0 100644
--- a/core/composer.lock
+++ b/core/composer.lock
@@ -4,7 +4,7 @@
         "Read more about it at http://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file",
         "This file is @generated automatically"
     ],
-    "hash": "377cea36943eae1762c885ef742bc320",
+    "hash": "a1f5c8c7e6843c8fdde4e03c7a383ecb",
     "packages": [
         {
             "name": "behat/mink",
@@ -940,6 +940,48 @@
             "time": "2014-10-12 19:18:40"
         },
         {
+            "name": "ircmaxell/password-compat",
+            "version": "v1.0.4",
+            "source": {
+                "type": "git",
+                "url": "https://github.com/ircmaxell/password_compat.git",
+                "reference": "5c5cde8822a69545767f7c7f3058cb15ff84614c"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://api.github.com/repos/ircmaxell/password_compat/zipball/5c5cde8822a69545767f7c7f3058cb15ff84614c",
+                "reference": "5c5cde8822a69545767f7c7f3058cb15ff84614c",
+                "shasum": ""
+            },
+            "require-dev": {
+                "phpunit/phpunit": "4.*"
+            },
+            "type": "library",
+            "autoload": {
+                "files": [
+                    "lib/password.php"
+                ]
+            },
+            "notification-url": "https://packagist.org/downloads/",
+            "license": [
+                "MIT"
+            ],
+            "authors": [
+                {
+                    "name": "Anthony Ferrara",
+                    "email": "ircmaxell@php.net",
+                    "homepage": "http://blog.ircmaxell.com"
+                }
+            ],
+            "description": "A compatibility library for the proposed simplified password hashing algorithm: https://wiki.php.net/rfc/password_hash",
+            "homepage": "https://github.com/ircmaxell/password_compat",
+            "keywords": [
+                "hashing",
+                "password"
+            ],
+            "time": "2014-11-20 16:49:30"
+        },
+        {
             "name": "masterminds/html5",
             "version": "2.1.0",
             "source": {
diff --git a/core/core.services.yml b/core/core.services.yml
index 2b81197..796fdb7 100644
--- a/core/core.services.yml
+++ b/core/core.services.yml
@@ -658,14 +658,12 @@ services:
     arguments: ['@router', '@router.no_access_checks', '@current_user', '@path_processor_manager']
 
 # The argument to the hashing service defined in services.yml, to the
-# constructor of PhpassHashedPassword is the log2 number of iterations for
-# password stretching.
+# constructor of Password is the 'cost' option of password_hash().
 # @todo increase by 1 every Drupal version in order to counteract increases in
-# the speed and power of computers available to crack the hashes. The current
-# password hashing method was introduced in Drupal 7 with a log2 count of 15.
+# the speed and power of computers available to crack the hashes.
   password:
-    class: Drupal\Core\Password\PhpassHashedPassword
-    arguments: [16]
+    class: Drupal\Core\Password\Password
+    arguments: [10]
   accept_header_matcher:
     class: Drupal\Core\Routing\AcceptHeaderMatcher
     arguments: ['@content_negotiation']
diff --git a/core/lib/Drupal/Core/Password/PhpassHashedPassword.php b/core/lib/Drupal/Core/Password/PhpassHashedPassword.php
deleted file mode 100644
index 17cafdd..0000000
--- a/core/lib/Drupal/Core/Password/PhpassHashedPassword.php
+++ /dev/null
@@ -1,268 +0,0 @@
-<?php
-
-/**
- * @file
- * Definition of Drupal\Core\Password\PhpassHashedPassword
- */
-
-namespace Drupal\Core\Password;
-
-use Drupal\Component\Utility\Crypt;
-use Drupal\user\UserInterface;
-
-/**
- * Secure password hashing functions based on the Portable PHP password
- * hashing framework.
- *
- * @see http://www.openwall.com/phpass/
- */
-class PhpassHashedPassword implements PasswordInterface {
-  /**
-   * The minimum allowed log2 number of iterations for password stretching.
-   */
-  const MIN_HASH_COUNT = 7;
-
-  /**
-   * The maximum allowed log2 number of iterations for password stretching.
-   */
-  const MAX_HASH_COUNT = 30;
-
-  /**
-   * The expected (and maximum) number of characters in a hashed password.
-   */
-  const HASH_LENGTH = 55;
-
-  /**
-   * Returns a string for mapping an int to the corresponding base 64 character.
-   */
-  static $ITOA64 = './0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz';
-
-  /**
-   * Specifies the number of times the hashing function will be applied when
-   * generating new password hashes. The number of times is calculated by
-   * raising 2 to the power of the given value.
-   */
-  protected $countLog2;
-
-  /**
-   * Constructs a new phpass password hashing instance.
-   *
-   * @param int $countLog2
-   *   Password stretching iteration count. Specifies the number of times the
-   *   hashing function will be applied when generating new password hashes.
-   *   The number of times is calculated by raising 2 to the power of the given
-   *   value.
-   */
-  function __construct($countLog2) {
-    // Ensure that $countLog2 is within set bounds.
-    $this->countLog2 = $this->enforceLog2Boundaries($countLog2);
-  }
-
-  /**
-   * Encodes bytes into printable base 64 using the *nix standard from crypt().
-   *
-   * @param String $input
-   *   The string containing bytes to encode.
-   * @param Integer $count
-   *   The number of characters (bytes) to encode.
-   *
-   * @return String
-   *   Encoded string
-   */
-  protected function base64Encode($input, $count) {
-    $output = '';
-    $i = 0;
-    do {
-      $value = ord($input[$i++]);
-      $output .= static::$ITOA64[$value & 0x3f];
-      if ($i < $count) {
-        $value |= ord($input[$i]) << 8;
-      }
-      $output .= static::$ITOA64[($value >> 6) & 0x3f];
-      if ($i++ >= $count) {
-        break;
-      }
-      if ($i < $count) {
-        $value |= ord($input[$i]) << 16;
-      }
-      $output .= static::$ITOA64[($value >> 12) & 0x3f];
-      if ($i++ >= $count) {
-        break;
-      }
-      $output .= static::$ITOA64[($value >> 18) & 0x3f];
-    } while ($i < $count);
-
-    return $output;
-  }
-
-  /**
-   * Generates a random base 64-encoded salt prefixed with settings for the hash.
-   *
-   * Proper use of salts may defeat a number of attacks, including:
-   *  - The ability to try candidate passwords against multiple hashes at once.
-   *  - The ability to use pre-hashed lists of candidate passwords.
-   *  - The ability to determine whether two users have the same (or different)
-   *    password without actually having to guess one of the passwords.
-   *
-   * @return String
-   *   A 12 character string containing the iteration count and a random salt.
-   */
-  protected function generateSalt() {
-    $output = '$S$';
-    // 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(Crypt::randomBytes(6), 6);
-    return $output;
-  }
-
-  /**
-   * Ensures that $count_log2 is within set bounds.
-   *
-   * @param Integer $count_log2
-   *   Integer that determines the number of iterations used in the hashing
-   *   process. A larger value is more secure, but takes more time to complete.
-   *
-   * @return Integer
-   *   Integer within set bounds that is closest to $count_log2.
-   */
-  protected function enforceLog2Boundaries($count_log2) {
-    if ($count_log2 < static::MIN_HASH_COUNT) {
-      return static::MIN_HASH_COUNT;
-    }
-    elseif ($count_log2 > static::MAX_HASH_COUNT) {
-      return static::MAX_HASH_COUNT;
-    }
-
-    return (int) $count_log2;
-  }
-
-  /**
-   * Hash a password using a secure stretched hash.
-   *
-   * By using a salt and repeated hashing the password is "stretched". Its
-   * security is increased because it becomes much more computationally costly
-   * for an attacker to try to break the hash by brute-force computation of the
-   * hashes of a large number of plain-text words or strings to find a match.
-   *
-   * @param String $algo
-   *   The string name of a hashing algorithm usable by hash(), like 'sha256'.
-   * @param String $password
-   *   Plain-text password up to 512 bytes (128 to 512 UTF-8 characters) to
-   *   hash.
-   * @param String $setting
-   *   An existing hash or the output of $this->generateSalt().  Must be
-   *   at least 12 characters (the settings and salt).
-   *
-   * @return String
-   *   A string containing the hashed password (and salt) or FALSE on failure.
-   *   The return string will be truncated at HASH_LENGTH characters max.
-   */
-  protected function crypt($algo, $password, $setting) {
-    // Prevent DoS attacks by refusing to hash large passwords.
-    if (strlen($password) > 512) {
-      return FALSE;
-    }
-
-    // The first 12 characters of an existing hash are its setting string.
-    $setting = substr($setting, 0, 12);
-
-    if ($setting[0] != '$' || $setting[2] != '$') {
-      return FALSE;
-    }
-    $count_log2 = $this->getCountLog2($setting);
-    // Stored hashes may have been crypted with any iteration count. However we
-    // do not allow applying the algorithm for unreasonable low and high values
-    // respectively.
-    if ($count_log2 != $this->enforceLog2Boundaries($count_log2)) {
-      return FALSE;
-    }
-    $salt = substr($setting, 4, 8);
-    // Hashes must have an 8 character salt.
-    if (strlen($salt) != 8) {
-      return FALSE;
-    }
-
-    // Convert the base 2 logarithm into an integer.
-    $count = 1 << $count_log2;
-
-    // We rely on the hash() function being available in PHP 5.2+.
-    $hash = hash($algo, $salt . $password, TRUE);
-    do {
-      $hash = hash($algo, $hash . $password, TRUE);
-    } while (--$count);
-
-    $len = strlen($hash);
-    $output =  $setting . $this->base64Encode($hash, $len);
-    // $this->base64Encode() of a 16 byte MD5 will always be 22 characters.
-    // $this->base64Encode() of a 64 byte sha512 will always be 86 characters.
-    $expected = 12 + ceil((8 * $len) / 6);
-    return (strlen($output) == $expected) ? substr($output, 0, static::HASH_LENGTH) : FALSE;
-  }
-
-  /**
-   * Parse the log2 iteration count from a stored hash or setting string.
-   *
-   * @param String $setting
-   *   An existing hash or the output of $this->generateSalt().  Must be
-   *   at least 12 characters (the settings and salt).
-   */
-  public function getCountLog2($setting) {
-    return strpos(static::$ITOA64, $setting[3]);
-  }
-
-  /**
-   * Implements Drupal\Core\Password\PasswordInterface::hash().
-   */
-  public function hash($password) {
-    return $this->crypt('sha512', $password, $this->generateSalt());
-  }
-
-  /**
-   * Implements Drupal\Core\Password\PasswordInterface::checkPassword().
-   */
-  public function check($password, UserInterface $account) {
-    if (substr($account->getPassword(), 0, 2) == 'U$') {
-      // This may be an updated password from user_update_7000(). Such hashes
-      // have 'U' added as the first character and need an extra md5() (see the
-      // Drupal 7 documentation).
-      $stored_hash = substr($account->getPassword(), 1);
-      $password = md5($password);
-    }
-    else {
-      $stored_hash = $account->getPassword();
-    }
-
-    $type = substr($stored_hash, 0, 3);
-    switch ($type) {
-      case '$S$':
-        // A normal Drupal 7 password using sha512.
-        $hash = $this->crypt('sha512', $password, $stored_hash);
-        break;
-      case '$H$':
-        // phpBB3 uses "$H$" for the same thing as "$P$".
-      case '$P$':
-        // A phpass password generated using md5.  This is an
-        // imported password or from an earlier Drupal version.
-        $hash = $this->crypt('md5', $password, $stored_hash);
-        break;
-      default:
-        return FALSE;
-    }
-    return ($hash && $stored_hash == $hash);
-  }
-
-  /**
-   * Implements Drupal\Core\Password\PasswordInterface::userNeedsNewHash().
-   */
-  public function userNeedsNewHash(UserInterface $account) {
-    // Check whether this was an updated password.
-    if ((substr($account->getPassword(), 0, 3) != '$S$') || (strlen($account->getPassword()) != static::HASH_LENGTH)) {
-      return TRUE;
-    }
-    // Ensure that $count_log2 is within set bounds.
-    $count_log2 = $this->enforceLog2Boundaries($this->countLog2);
-    // Check whether the iteration count used differs from the standard number.
-    return ($this->getCountLog2($account->getPassword()) !== $count_log2);
-  }
-}
diff --git a/core/modules/migrate/src/MigratePassword.php b/core/modules/migrate/src/MigratePassword.php
index ba42e8a..796c7f1 100644
--- a/core/modules/migrate/src/MigratePassword.php
+++ b/core/modules/migrate/src/MigratePassword.php
@@ -59,10 +59,22 @@ public function userNeedsNewHash(UserInterface $account) {
   public function hash($password) {
     $hash = $this->originalPassword->hash($password);
 
-    // Allow prefixing only if the service was asked to prefix. Check also if
-    // the $password pattern is conforming to a MD5 result.
-    if ($this->enabled && preg_match('/^[0-9a-f]{32}$/', $password)) {
-      $hash = 'U' . $hash;
+    // Allow prefixing only if the service was asked to prefix.
+    if ($this->enabled) {
+      // If the $password pattern is conforming to a MD5 result this is most
+      // likely a Drupal 6 hashed password.
+      if (preg_match('/^[0-9a-f]{32}$/', $password)) {
+        $hash = 'U' . $hash;
+      }
+      // @todo Is this enough? Maybe we should pass and test somehow the current
+      // migration source to detect a Drupal 7 source. This can be done by
+      // injecting the current migration when enabling prefixing in
+      // Drupal\migrate\Plugin\migrate\destination\EntityUser. In that case
+      // ::enableMd5Prefixing() needs to be renamed. Or pass the migration into
+      // constructor? How?
+      if (substr($password, 0, 3) == '$S$') {
+        $hash = 'D7' . $hash;
+      }
     }
 
     return $hash;
diff --git a/core/vendor/composer/autoload_files.php b/core/vendor/composer/autoload_files.php
index 853f9a0..d257539 100644
--- a/core/vendor/composer/autoload_files.php
+++ b/core/vendor/composer/autoload_files.php
@@ -7,5 +7,6 @@
 
 return array(
     $vendorDir . '/react/promise/src/functions_include.php',
+    $vendorDir . '/ircmaxell/password-compat/lib/password.php',
     $baseDir . '/lib/Drupal.php',
 );
diff --git a/core/vendor/composer/installed.json b/core/vendor/composer/installed.json
index 314ce82..5481bc3 100644
--- a/core/vendor/composer/installed.json
+++ b/core/vendor/composer/installed.json
@@ -3133,5 +3133,49 @@
             "serializer",
             "xml"
         ]
+    },
+    {
+        "name": "ircmaxell/password-compat",
+        "version": "v1.0.4",
+        "version_normalized": "1.0.4.0",
+        "source": {
+            "type": "git",
+            "url": "https://github.com/ircmaxell/password_compat.git",
+            "reference": "5c5cde8822a69545767f7c7f3058cb15ff84614c"
+        },
+        "dist": {
+            "type": "zip",
+            "url": "https://api.github.com/repos/ircmaxell/password_compat/zipball/5c5cde8822a69545767f7c7f3058cb15ff84614c",
+            "reference": "5c5cde8822a69545767f7c7f3058cb15ff84614c",
+            "shasum": ""
+        },
+        "require-dev": {
+            "phpunit/phpunit": "4.*"
+        },
+        "time": "2014-11-20 16:49:30",
+        "type": "library",
+        "installation-source": "dist",
+        "autoload": {
+            "files": [
+                "lib/password.php"
+            ]
+        },
+        "notification-url": "https://packagist.org/downloads/",
+        "license": [
+            "MIT"
+        ],
+        "authors": [
+            {
+                "name": "Anthony Ferrara",
+                "email": "ircmaxell@php.net",
+                "homepage": "http://blog.ircmaxell.com"
+            }
+        ],
+        "description": "A compatibility library for the proposed simplified password hashing algorithm: https://wiki.php.net/rfc/password_hash",
+        "homepage": "https://github.com/ircmaxell/password_compat",
+        "keywords": [
+            "hashing",
+            "password"
+        ]
     }
 ]
