diff --git a/core/lib/Drupal/Core/Password/PhpassHashedPassword.php b/core/lib/Drupal/Core/Password/PhpassHashedPassword.php
index b047a8d..17cafdd 100644
--- a/core/lib/Drupal/Core/Password/PhpassHashedPassword.php
+++ b/core/lib/Drupal/Core/Password/PhpassHashedPassword.php
@@ -148,7 +148,8 @@ protected function enforceLog2Boundaries($count_log2) {
    * @param String $algo
    *   The string name of a hashing algorithm usable by hash(), like 'sha256'.
    * @param String $password
-   *   The plain-text password to hash.
+   *   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).
@@ -158,6 +159,11 @@ protected function enforceLog2Boundaries($count_log2) {
    *   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);
 
diff --git a/core/tests/Drupal/Tests/Core/Password/PasswordHashingTest.php b/core/tests/Drupal/Tests/Core/Password/PasswordHashingTest.php
index bdae806..f304be0 100644
--- a/core/tests/Drupal/Tests/Core/Password/PasswordHashingTest.php
+++ b/core/tests/Drupal/Tests/Core/Password/PasswordHashingTest.php
@@ -137,6 +137,46 @@ public function testPasswordRehashing() {
     $this->assertTrue($this->passwordHasher->check($this->password, $this->user), 'Password check succeeds with re-hashed password.');
   }
 
+  /**
+   * Verifies that passwords longer than 512 bytes are not hashed.
+   *
+   * @covers ::crypt
+   *
+   * @dataProvider providerLongPasswords
+   */
+  public function testLongPassword($password, $allowed) {
+
+    $hashed_password = $this->passwordHasher->hash($password);
+
+    if ($allowed) {
+      $this->assertNotFalse($hashed_password);
+    }
+    else {
+      $this->assertFalse($hashed_password);
+    }
+  }
+
+  /**
+   * Provides the test matrix for testLongPassword().
+   */
+  public function providerLongPasswords() {
+    // '512 byte long password is allowed.'
+    $passwords['allowed'] = array(str_repeat('x', 512), TRUE);
+    // 513 byte long password is not allowed.
+    $passwords['too_long'] = array(str_repeat('x', 513), FALSE);
+
+    // Check a string of 3-byte UTF-8 characters, 510 byte long password is
+    // allowed.
+    $passwords['utf8'] = array(str_repeat('€', 170), TRUE);
+    // 512 byte long password is allowed.
+    $passwords['ut8_extended'] = array($passwords['utf8'][0] . 'xx', TRUE);
+
+    // Check a string of 3-byte UTF-8 characters, 513 byte long password is
+    // allowed.
+    $passwords['utf8_too_long'] = array(str_repeat('€', 171), FALSE);
+    return $passwords;
+  }
+
 }
 
 /**
