diff --git a/core/lib/Drupal/Component/Utility/Crypt.php b/core/lib/Drupal/Component/Utility/Crypt.php
index 7144e3b..6d101c2 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 b74c05d..f2b015c 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 5b823a2..38f1ad6 100644
--- a/core/tests/Drupal/Tests/Core/Access/CsrfTokenGeneratorTest.php
+++ b/core/tests/Drupal/Tests/Core/Access/CsrfTokenGeneratorTest.php
@@ -68,10 +68,21 @@ public function testValidate() {
     $this->assertTrue($this->generator->validate($token));
     $this->assertFalse($this->generator->validate($token, 'foo'));
 
-
     $token = $this->generator->get('bar');
     $this->assertTrue($this->generator->validate($token, 'bar'));
 
+    // The following checks will throw PHP fatals and notices, so we disable
+    // error assertions.
+    set_error_handler(array($this, "errorHandler"));
+    $this->assertFalse($this->generator->validate(NULL, new \stdClass()), 'Token NULL, value object returns FALSE.');
+    $this->assertFalse($this->generator->validate(0, array()), 'Token 0, value array returns FALSE.');
+    $this->assertFalse($this->generator->validate('', array()), "Token '', value array returns FALSE.");
+    $this->assertFalse('' === $this->generator->validate(array()), 'Token generation does not return an empty string on invalid parameters.');
+    restore_error_handler();
+
+    $this->assertFalse($this->generator->validate(TRUE, 'foo'), 'Token TRUE, value foo returns FALSE.');
+    $this->assertFalse($this->generator->validate(0, 'foo'), 'Token 0, value foo returns FALSE.');
+
     // Check the skip_anonymous option with both a anonymous user and a real
     // user.
     $account = $this->getMock('Drupal\Core\Session\AccountInterface');
@@ -90,6 +101,13 @@ public function testValidate() {
     $this->assertFalse($this->generator->validate($token, 'foo', TRUE));
   }
 
+  /**
+   * Provides a custom error handler that disables all reporting.
+   */
+  public function errorHandler($errno, $errstr, $errfile, $errline, $errcontext) {
+    return TRUE;
+  }
+
 }
 
 }
