diff --git a/core/lib/Drupal/Component/Utility/Crypt.php b/core/lib/Drupal/Component/Utility/Crypt.php
index 7144e3b549909d0fbd1acfac7f4810e67d2c322a..6d101c2b56b12d958e799517a44de90ef176a083 100644
--- a/core/lib/Drupal/Component/Utility/Crypt.php
+++ b/core/lib/Drupal/Component/Utility/Crypt.php
@@ -81,7 +81,11 @@ public static function randomBytes($count) {
    *   any = padding characters removed.
    */
   public static function hmacBase64($data, $key) {
-    $hmac = base64_encode(hash_hmac('sha256', $data, $key, TRUE));
+    // Casting $data and $key to strings here is necessary to avoid empty string
+    // results of the hash function if they are not scalar values. As this
+    // function is used in security-critical contexts like token validation it is
+    // important that it never returns an empty string.
+    $hmac = base64_encode(hash_hmac('sha256', (string) $data, (string) $key, TRUE));
     // Modify the hmac so it's safe to use in URLs.
     return strtr($hmac, array('+' => '-', '/' => '_', '=' => ''));
   }
diff --git a/core/lib/Drupal/Core/Access/CsrfTokenGenerator.php b/core/lib/Drupal/Core/Access/CsrfTokenGenerator.php
index b74c05d8b4309a40b84834ac6554244944fb731f..f2b015cfb2becd836caf16cb100498736fb360c1 100644
--- a/core/lib/Drupal/Core/Access/CsrfTokenGenerator.php
+++ b/core/lib/Drupal/Core/Access/CsrfTokenGenerator.php
@@ -84,7 +84,7 @@ public function get($value = '') {
    *   is TRUE, the return value will always be TRUE for anonymous users.
    */
   public function validate($token, $value = '', $skip_anonymous = FALSE) {
-    return ($skip_anonymous && $this->currentUser->isAnonymous()) || ($token == $this->get($value));
+    return ($skip_anonymous && $this->currentUser->isAnonymous()) || ($token === $this->get($value));
   }
 
 }
diff --git a/core/tests/Drupal/Tests/Core/Access/CsrfTokenGeneratorTest.php b/core/tests/Drupal/Tests/Core/Access/CsrfTokenGeneratorTest.php
index 5b823a2a1bc336149697e4520c72955d060fb839..0db8f21438952320e84d349d1b751992cb160274 100644
--- a/core/tests/Drupal/Tests/Core/Access/CsrfTokenGeneratorTest.php
+++ b/core/tests/Drupal/Tests/Core/Access/CsrfTokenGeneratorTest.php
@@ -90,6 +90,43 @@ public function testValidate() {
     $this->assertFalse($this->generator->validate($token, 'foo', TRUE));
   }
 
+  /**
+   * Tests CsrfTokenGenerator::validate() with different parameter types.
+   *
+   * @param mixed $token
+   *   The token to be validated.
+   * @param mixed $value
+   *   (optional) An additional value to base the token on.
+   * @param mixed $expected
+   *   (optional) The expected result of validate(). Defaults to FALSE.
+   *
+   * @dataProvider providerTestValidateParameterTypes
+   */
+  public function testValidateParameterTypes($token, $value = '', $expected = FALSE) {
+    // The following check might throw PHP fatals and notices, so we disable
+    // error assertions.
+    set_error_handler(function () {return TRUE;});
+    $this->assertSame($expected, $this->generator->validate($token, $value));
+    restore_error_handler();
+  }
+
+  /**
+   * Provides data for the validate test.
+   *
+   * @return array
+   *   An array of data used by the test.
+   */
+  public function providerTestValidateParameterTypes() {
+    return array(
+      array(NULL, new \stdClass()),
+      array(0, array()),
+      array('', array()),
+      array(array()),
+      array(TRUE, 'foo'),
+      array(0, 'foo'),
+    );
+  }
+
 }
 
 }