diff --git a/core/core.services.yml b/core/core.services.yml
index 025368ec3c8b237ae7d6e0f467ec8671d719e590..3f7c394aec5e7bb3e64f73ae5a06f6b52a2c5de6 100644
--- a/core/core.services.yml
+++ b/core/core.services.yml
@@ -127,15 +127,23 @@ services:
     arguments: ['@service_container', '@settings']
   keyvalue.database:
     class: Drupal\Core\KeyValueStore\KeyValueDatabaseFactory
-    arguments: ['@database']
+    arguments: ['@serialization.phpserialize', '@database']
   keyvalue.expirable:
     class: Drupal\Core\KeyValueStore\KeyValueExpirableFactory
     arguments: ['@service_container', '@settings']
   keyvalue.expirable.database:
     class: Drupal\Core\KeyValueStore\KeyValueDatabaseExpirableFactory
+    arguments: ['@serialization.phpserialize', '@database']
     tags:
       - { name: needs_destruction }
-    arguments: ['@database']
+
+  serialization.json:
+    class: Drupal\Component\Serialization\Json
+  serialization.phpserialize:
+    class: Drupal\Component\Serialization\PhpSerialize
+  serialization.yaml:
+    class: Drupal\Component\Serialization\Yaml
+
   settings:
     class: Drupal\Component\Utility\Settings
     factory_class: Drupal\Component\Utility\Settings
@@ -288,7 +296,7 @@ services:
     arguments: ['@database']
   user.tempstore:
     class: Drupal\user\TempStoreFactory
-    arguments: ['@database', '@lock']
+    arguments: ['@serialization.phpserialize', '@database', '@lock']
   router.request_context:
     class: Symfony\Component\Routing\RequestContext
     tags:
diff --git a/core/lib/Drupal/Component/Serialization/Json.php b/core/lib/Drupal/Component/Serialization/Json.php
index 91081d7e46dcba53800f086af614e9933f6a387d..3349a3ae173cfb47212f4e57bba6a1b5af9d48c1 100644
--- a/core/lib/Drupal/Component/Serialization/Json.php
+++ b/core/lib/Drupal/Component/Serialization/Json.php
@@ -8,44 +8,32 @@
 namespace Drupal\Component\Serialization;
 
 /**
- * Provides helpers for dealing with json.
- *
- * @ingroup utility
+ * Default serialization for JSON.
  */
-class Json {
+class Json implements SerializationInterface {
 
   /**
-   * Converts a PHP variable into its JavaScript equivalent.
+   * {@inheritdoc}
    *
-   * We use HTML-safe strings, with several characters escaped.
-   *
-   * @param mixed $variable
-   *   The variable to encode.
-   *
-   * @return string
-   *   Returns the encoded variable.
-   *
-   * @see drupal_json_decode()
-   * @ingroup php_wrappers
+   * Uses HTML-safe strings, with several characters escaped.
    */
   public static function encode($variable) {
-    // Encode <, >, ', &, and " using the json_encode() options parameter.
+    // Encode <, >, ', &, and ".
     return json_encode($variable, JSON_HEX_TAG | JSON_HEX_APOS | JSON_HEX_AMP | JSON_HEX_QUOT);
   }
 
   /**
-   * Converts an HTML-safe JSON string into its PHP equivalent.
-   *
-   * @param string $string
-   *   The string to decode.
-   *
-   * @return mixed
-   *   Returns the decoded string.
-   *
-   * @ingroup php_wrappers
+   * {@inheritdoc}
    */
   public static function decode($string) {
     return json_decode($string, TRUE);
   }
 
+  /**
+   * {@inheritdoc}
+   */
+  public static function getFileExtension() {
+    return 'json';
+  }
+
 }
diff --git a/core/lib/Drupal/Component/Serialization/PhpSerialize.php b/core/lib/Drupal/Component/Serialization/PhpSerialize.php
new file mode 100644
index 0000000000000000000000000000000000000000..a6f11fcfb570be854bf990a55aa84d16147e4474
--- /dev/null
+++ b/core/lib/Drupal/Component/Serialization/PhpSerialize.php
@@ -0,0 +1,36 @@
+<?php
+
+/**
+ * @file
+ * Contains \Drupal\Component\Serialization\PhpSerialize.
+ */
+
+namespace Drupal\Component\Serialization;
+
+/**
+ * Default serialization for serialized PHP.
+ */
+class PhpSerialize implements SerializationInterface {
+
+  /**
+   * {@inheritdoc}
+   */
+  public static function encode($data) {
+    return serialize($data);
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public static function decode($raw) {
+    return unserialize($raw);
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public static function getFileExtension() {
+    return 'serialized';
+  }
+
+}
diff --git a/core/lib/Drupal/Core/KeyValueStore/DatabaseStorage.php b/core/lib/Drupal/Core/KeyValueStore/DatabaseStorage.php
index 1464186339a74a6ca03dad926f1da79cc711cf02..d9893644f968a49929c9543643f03c59a3c513a0 100644
--- a/core/lib/Drupal/Core/KeyValueStore/DatabaseStorage.php
+++ b/core/lib/Drupal/Core/KeyValueStore/DatabaseStorage.php
@@ -7,6 +7,7 @@
 
 namespace Drupal\Core\KeyValueStore;
 
+use Drupal\Component\Serialization\SerializationInterface;
 use Drupal\Core\Database\Query\Merge;
 use Drupal\Core\Database\Connection;
 
@@ -18,6 +19,13 @@
  */
 class DatabaseStorage extends StorageBase {
 
+  /**
+   * The serialization class to use.
+   *
+   * @var \Drupal\Component\Serialization\SerializationInterface
+   */
+  protected $serializer;
+
   /**
    * The database connection.
    *
@@ -37,11 +45,16 @@ class DatabaseStorage extends StorageBase {
    *
    * @param string $collection
    *   The name of the collection holding key and value pairs.
+   * @param \Drupal\Component\Serialization\SerializationInterface $serializer
+   *   The serialization class to use.
+   * @param \Drupal\Core\Database\Connection $connection
+   *   The database connection to use.
    * @param string $table
    *   The name of the SQL table to use, defaults to key_value.
    */
-  public function __construct($collection, Connection $connection, $table = 'key_value') {
+  public function __construct($collection, SerializationInterface $serializer, Connection $connection, $table = 'key_value') {
     parent::__construct($collection);
+    $this->serializer = $serializer;
     $this->connection = $connection;
     $this->table = $table;
   }
@@ -65,7 +78,7 @@ public function getMultiple(array $keys) {
       $result = $this->connection->query('SELECT name, value FROM {' . $this->connection->escapeTable($this->table) . '} WHERE name IN (:keys) AND collection = :collection', array(':keys' => $keys, ':collection' => $this->collection))->fetchAllAssoc('name');
       foreach ($keys as $key) {
         if (isset($result[$key])) {
-          $values[$key] = unserialize($result[$key]->value);
+          $values[$key] = $this->serializer->decode($result[$key]->value);
         }
       }
     }
@@ -86,7 +99,7 @@ public function getAll() {
 
     foreach ($result as $item) {
       if ($item) {
-        $values[$item->name] = unserialize($item->value);
+        $values[$item->name] = $this->serializer->decode($item->value);
       }
     }
     return $values;
@@ -101,7 +114,7 @@ public function set($key, $value) {
         'name' => $key,
         'collection' => $this->collection,
       ))
-      ->fields(array('value' => serialize($value)))
+      ->fields(array('value' => $this->serializer->encode($value)))
       ->execute();
   }
 
@@ -113,7 +126,7 @@ public function setIfNotExists($key, $value) {
       ->insertFields(array(
         'collection' => $this->collection,
         'name' => $key,
-        'value' => serialize($value),
+        'value' => $this->serializer->encode($value),
       ))
       ->condition('collection', $this->collection)
       ->condition('name', $key)
diff --git a/core/lib/Drupal/Core/KeyValueStore/DatabaseStorageExpirable.php b/core/lib/Drupal/Core/KeyValueStore/DatabaseStorageExpirable.php
index fb0b8b0a7ca4eb1a9cf8041501396ecb1d92b9d0..3263a47e0673edd33517e2a3356950cff3a2ec3d 100644
--- a/core/lib/Drupal/Core/KeyValueStore/DatabaseStorageExpirable.php
+++ b/core/lib/Drupal/Core/KeyValueStore/DatabaseStorageExpirable.php
@@ -7,6 +7,7 @@
 
 namespace Drupal\Core\KeyValueStore;
 
+use Drupal\Component\Serialization\SerializationInterface;
 use Drupal\Core\DestructableInterface;
 use Drupal\Core\Database\Connection;
 use Drupal\Core\Database\Query\Merge;
@@ -19,13 +20,6 @@
  */
 class DatabaseStorageExpirable extends DatabaseStorage implements KeyValueStoreExpirableInterface, DestructableInterface {
 
-  /**
-   * The connection object for this storage.
-   *
-   * @var \Drupal\Core\Database\Connection
-   */
-  protected $connection;
-
   /**
    * Flag indicating whether garbage collection should be performed.
    *
@@ -44,16 +38,15 @@ class DatabaseStorageExpirable extends DatabaseStorage implements KeyValueStoreE
    *
    * @param string $collection
    *   The name of the collection holding key and value pairs.
-   * @param array $options
-   *   An associative array of options for the key/value storage collection.
-   *   Keys used:
-   *   - connection: (optional) The database connection to use for storing the
-   *     data. Defaults to the current connection.
-   *   - table: (optional) The name of the SQL table to use. Defaults to
-   *     key_value_expire.
+   * @param \Drupal\Component\Serialization\SerializationInterface $serializer
+   *   The serialization class to use.
+   * @param \Drupal\Core\Database\Connection $connection
+   *   The database connection to use.
+   * @param string $table
+   *   The name of the SQL table to use, defaults to key_value_expire.
    */
-  public function __construct($collection, Connection $connection, $table = 'key_value_expire') {
-    parent::__construct($collection, $connection, $table);
+  public function __construct($collection, SerializationInterface $serializer, Connection $connection, $table = 'key_value_expire') {
+    parent::__construct($collection, $serializer, $connection, $table);
   }
 
   /**
@@ -78,7 +71,7 @@ public function getMultiple(array $keys) {
         ':keys' => $keys,
         ':collection' => $this->collection,
       ))->fetchAllKeyed();
-    return array_map('unserialize', $values);
+    return array_map(array($this->serializer, 'decode'), $values);
   }
 
   /**
@@ -91,7 +84,7 @@ public function getAll() {
         ':collection' => $this->collection,
         ':now' => REQUEST_TIME
       ))->fetchAllKeyed();
-    return array_map('unserialize', $values);
+    return array_map(array($this->serializer, 'decode'), $values);
   }
 
   /**
@@ -107,7 +100,7 @@ function setWithExpire($key, $value, $expire) {
         'collection' => $this->collection,
       ))
       ->fields(array(
-        'value' => serialize($value),
+        'value' => $this->serializer->encode($value),
         'expire' => REQUEST_TIME + $expire,
       ))
       ->execute();
@@ -124,7 +117,7 @@ function setWithExpireIfNotExists($key, $value, $expire) {
       ->insertFields(array(
         'collection' => $this->collection,
         'name' => $key,
-        'value' => serialize($value),
+        'value' => $this->serializer->encode($value),
         'expire' => REQUEST_TIME + $expire,
       ))
       ->condition('collection', $this->collection)
diff --git a/core/lib/Drupal/Core/KeyValueStore/KeyValueDatabaseExpirableFactory.php b/core/lib/Drupal/Core/KeyValueStore/KeyValueDatabaseExpirableFactory.php
index 9000e20c15e1125937a75f7d546364e3e8e27417..5ff8ae6f503f9536094610067b6aae5f48b15b93 100644
--- a/core/lib/Drupal/Core/KeyValueStore/KeyValueDatabaseExpirableFactory.php
+++ b/core/lib/Drupal/Core/KeyValueStore/KeyValueDatabaseExpirableFactory.php
@@ -7,6 +7,7 @@
 
 namespace Drupal\Core\KeyValueStore;
 
+use Drupal\Component\Serialization\SerializationInterface;
 use Drupal\Core\DestructableInterface;
 use Drupal\Core\Database\Connection;
 
@@ -22,6 +23,13 @@ class KeyValueDatabaseExpirableFactory implements KeyValueExpirableFactoryInterf
    */
   protected $storages = array();
 
+  /**
+   * The serialization class to use.
+   *
+   * @var \Drupal\Component\Serialization\SerializationInterface
+   */
+  protected $serializer;
+
   /**
    * The database connection.
    *
@@ -32,11 +40,13 @@ class KeyValueDatabaseExpirableFactory implements KeyValueExpirableFactoryInterf
   /**
    * Constructs this factory object.
    *
-   *
+   * @param \Drupal\Component\Serialization\SerializationInterface $serializer
+   *   The serialization class to use.
    * @param \Drupal\Core\Database\Connection $connection
    *   The Connection object containing the key-value tables.
    */
-  function __construct(Connection $connection) {
+  function __construct(SerializationInterface $serializer, Connection $connection) {
+    $this->serializer = $serializer;
     $this->connection = $connection;
   }
 
@@ -45,7 +55,7 @@ function __construct(Connection $connection) {
    */
   public function get($collection) {
     if (!isset($this->storages[$collection])) {
-      $this->storages[$collection] = new DatabaseStorageExpirable($collection, $this->connection);
+      $this->storages[$collection] = new DatabaseStorageExpirable($collection, $this->serializer, $this->connection);
     }
     return $this->storages[$collection];
   }
diff --git a/core/lib/Drupal/Core/KeyValueStore/KeyValueDatabaseFactory.php b/core/lib/Drupal/Core/KeyValueStore/KeyValueDatabaseFactory.php
index 1a840b39c4000aafa40c1441ed85cdd595c150f4..391b08edd4a1631c9d1b57948cd636c6054ae609 100644
--- a/core/lib/Drupal/Core/KeyValueStore/KeyValueDatabaseFactory.php
+++ b/core/lib/Drupal/Core/KeyValueStore/KeyValueDatabaseFactory.php
@@ -6,6 +6,8 @@
  */
 
 namespace Drupal\Core\KeyValueStore;
+
+use Drupal\Component\Serialization\SerializationInterface;
 use Drupal\Core\Database\Connection;
 use Drupal\Core\Database\Database;
 
@@ -15,13 +17,29 @@
 class KeyValueDatabaseFactory implements KeyValueFactoryInterface {
 
   /**
-   * Constructs this factory object.
+   * The serialization class to use.
+   *
+   * @var \Drupal\Component\Serialization\SerializationInterface
+   */
+  protected $serializer;
+
+  /**
+   * The database connection to use.
    *
+   * @var \Drupal\Core\Database\Connection
+   */
+  protected $connection;
+
+  /**
+   * Constructs this factory object.
    *
+   * @param \Drupal\Component\Serialization\SerializationInterface $serializer
+   *   The serialization class to use.
    * @param \Drupal\Core\Database\Connection $connection
    *   The Connection object containing the key-value tables.
    */
-  function __construct(Connection $connection) {
+  function __construct(SerializationInterface $serializer, Connection $connection) {
+    $this->serializer = $serializer;
     $this->connection = $connection;
   }
 
@@ -29,6 +47,6 @@ function __construct(Connection $connection) {
    * {@inheritdoc}
    */
   public function get($collection) {
-    return new DatabaseStorage($collection, $this->connection);
+    return new DatabaseStorage($collection, $this->serializer, $this->connection);
   }
 }
diff --git a/core/modules/system/lib/Drupal/system/Tests/KeyValueStore/DatabaseStorageExpirableTest.php b/core/modules/system/lib/Drupal/system/Tests/KeyValueStore/DatabaseStorageExpirableTest.php
index 5f7365d8168f2040cf5432d96e07da6baeef6518..ed4236bc048329f80f942b2ce8d88fef3b723c9e 100644
--- a/core/modules/system/lib/Drupal/system/Tests/KeyValueStore/DatabaseStorageExpirableTest.php
+++ b/core/modules/system/lib/Drupal/system/Tests/KeyValueStore/DatabaseStorageExpirableTest.php
@@ -35,7 +35,10 @@ protected function setUp() {
       ->addArgument('default');
     $this->container
       ->register('keyvalue.expirable.database', 'Drupal\Core\KeyValueStore\KeyValueDatabaseExpirableFactory')
+      ->addArgument(new Reference('serialization.phpserialize'))
       ->addArgument(new Reference('database'));
+    $this->container
+      ->register('serialization.phpserialize', 'Drupal\Component\Serialization\PhpSerialize');
     $this->settingsSet('keyvalue_expirable_default', 'keyvalue.expirable.database');
   }
 
diff --git a/core/modules/system/lib/Drupal/system/Tests/KeyValueStore/DatabaseStorageTest.php b/core/modules/system/lib/Drupal/system/Tests/KeyValueStore/DatabaseStorageTest.php
index ad286d62c2800312d9b03b1c0ef0f46cc054f039..2254501df572d37e27e36fa6bfe93bd2bf7a3a2f 100644
--- a/core/modules/system/lib/Drupal/system/Tests/KeyValueStore/DatabaseStorageTest.php
+++ b/core/modules/system/lib/Drupal/system/Tests/KeyValueStore/DatabaseStorageTest.php
@@ -34,7 +34,10 @@ protected function setUp() {
       ->addArgument('default');
     $this->container
       ->register('keyvalue.database', 'Drupal\Core\KeyValueStore\KeyValueDatabaseFactory')
+      ->addArgument(new Reference('serialization.phpserialize'))
       ->addArgument(new Reference('database'));
+    $this->container
+      ->register('serialization.phpserialize', 'Drupal\Component\Serialization\PhpSerialize');
     $this->settingsSet('keyvalue_default', 'keyvalue.database');
   }
 
diff --git a/core/modules/system/lib/Drupal/system/Tests/KeyValueStore/GarbageCollectionTest.php b/core/modules/system/lib/Drupal/system/Tests/KeyValueStore/GarbageCollectionTest.php
index 2835a470c38a159068133bd05d31246bf12b784f..e583e75cb1ee45a4bcabafe87eebd9113260bfbc 100644
--- a/core/modules/system/lib/Drupal/system/Tests/KeyValueStore/GarbageCollectionTest.php
+++ b/core/modules/system/lib/Drupal/system/Tests/KeyValueStore/GarbageCollectionTest.php
@@ -7,6 +7,7 @@
 
 namespace Drupal\system\Tests\KeyValueStore;
 
+use Drupal\Component\Serialization\PhpSerialize;
 use Drupal\Core\Database\Database;
 use Drupal\Core\KeyValueStore\DatabaseStorageExpirable;
 use Drupal\simpletest\UnitTestBase;
@@ -41,7 +42,7 @@ protected function tearDown() {
    */
   public function testGarbageCollection() {
     $collection = $this->randomName();
-    $store = new DatabaseStorageExpirable($collection, Database::getConnection());
+    $store = new DatabaseStorageExpirable($collection, new PhpSerialize(), Database::getConnection());
 
     // Insert some items and confirm that they're set.
     for ($i = 0; $i <= 3; $i++) {
diff --git a/core/modules/user/lib/Drupal/user/TempStoreFactory.php b/core/modules/user/lib/Drupal/user/TempStoreFactory.php
index 28d4147b638df71a1d11b0a139d09b56fc9dcc2f..c93cb58ecded193a147b4320fcbecd8519fc4b09 100644
--- a/core/modules/user/lib/Drupal/user/TempStoreFactory.php
+++ b/core/modules/user/lib/Drupal/user/TempStoreFactory.php
@@ -7,6 +7,7 @@
 
 namespace Drupal\user;
 
+use Drupal\Component\Serialization\SerializationInterface;
 use Drupal\Core\Database\Connection;
 use Drupal\Core\KeyValueStore\DatabaseStorageExpirable;
 use Drupal\Core\Lock\LockBackendInterface;
@@ -16,6 +17,13 @@
  */
 class TempStoreFactory {
 
+  /**
+   * The serialization class to use.
+   *
+   * @var \Drupal\Component\Serialization\SerializationInterface
+   */
+  protected $serializer;
+
   /**
    * The connection object used for this data.
    *
@@ -33,12 +41,15 @@ class TempStoreFactory {
   /**
    * Constructs a Drupal\user\TempStoreFactory object.
    *
+   * @param \Drupal\Component\Serialization\SerializationInterface $serializer
+   *   The serialization class to use.
    * @param \Drupal\Core\Database\Connection $connection
    *   The connection object used for this data.
    * @param \Drupal\Core\Lock\LockBackendInterface $lockBackend
    *   The lock object used for this data.
    */
-  function __construct(Connection $connection, LockBackendInterface $lockBackend) {
+  function __construct(SerializationInterface $serializer, Connection $connection, LockBackendInterface $lockBackend) {
+    $this->serializer = $serializer;
     $this->connection = $connection;
     $this->lockBackend = $lockBackend;
   }
@@ -65,7 +76,7 @@ function get($collection, $owner = NULL) {
     }
 
     // Store the data for this collection in the database.
-    $storage = new DatabaseStorageExpirable($collection, $this->connection);
+    $storage = new DatabaseStorageExpirable($collection, $this->serializer, $this->connection);
     return new TempStore($storage, $this->lockBackend, $owner);
   }
 
diff --git a/core/modules/user/lib/Drupal/user/Tests/TempStoreDatabaseTest.php b/core/modules/user/lib/Drupal/user/Tests/TempStoreDatabaseTest.php
index 04378376a2a27f238a05fb91617bf09012e04e2e..1c83eb865be23e062cc3d845c69b900d48dbe20e 100644
--- a/core/modules/user/lib/Drupal/user/Tests/TempStoreDatabaseTest.php
+++ b/core/modules/user/lib/Drupal/user/Tests/TempStoreDatabaseTest.php
@@ -7,6 +7,7 @@
 
 namespace Drupal\user\Tests;
 
+use Drupal\Component\Serialization\PhpSerialize;
 use Drupal\simpletest\UnitTestBase;
 use Drupal\user\TempStoreFactory;
 use Drupal\Core\Lock\DatabaseLockBackend;
@@ -83,7 +84,7 @@ protected function tearDown() {
    */
   public function testUserTempStore() {
     // Create a key/value collection.
-    $factory = new TempStoreFactory(Database::getConnection(), new DatabaseLockBackend(Database::getConnection()));
+    $factory = new TempStoreFactory(new PhpSerialize(), Database::getConnection(), new DatabaseLockBackend(Database::getConnection()));
     $collection = $this->randomName();
 
     // Create two mock users.