diff --git a/django/contrib/sessions/backends/cookies.py b/django/contrib/sessions/backends/cookies.py
new file mode 100644
index 0000000..550d26b
--- /dev/null
+++ b/django/contrib/sessions/backends/cookies.py
@@ -0,0 +1,72 @@
+from django.conf import settings
+from django.core import signing
+
+from django.contrib.sessions.backends.base import SessionBase
+
+
+class SessionStore(SessionBase):
+
+    def load(self):
+        """
+        We load the data from the key itself instead of fetching from some
+        external data store.
+        """
+        try:
+            return signing.loads(self._session_key,
+                max_age=settings.SESSION_COOKIE_AGE,
+                salt='django.contrib.sessions.backends.cookies')
+        except (signing.BadSignature, ValueError):
+            self.create()
+            return {}
+
+    def create(self):
+        """
+        To create a new key, we simply make sure that the modified flag is set
+        so that the cookie is set on the client for the current request.
+        """
+        self.modified = True
+
+    def save(self):
+        """
+        To save, we get the session key as a securely signed string and then
+        set the modified flag so that the cookie is set on the client for the
+        current request.
+        """
+        self._session_key = self._get_session_key()
+        self.modified = True
+
+    def exists(self, session_key=None):
+        """
+        This method makes sense when you're talking to a shared resource, but
+        it doesn't matter when you're storing the information in the client's
+        cookie.
+        """
+        return False
+
+    def delete(self, session_key=None):
+        """
+        To delete, we clear the session key and the underlying data structure
+        and set the modified flag so that the cookie is set on the client for
+        the current request.
+        """
+        self._session_key = ''
+        self._session_cache = {}
+        self.modified = True
+
+    def cycle_key(self):
+        """
+        Keeps the same data but with a new key.  To do this, we just have to
+        call ``save()`` and it will automatically save a cookie with a new key
+        at the end of the request.
+        """
+        self.save()
+
+    def _get_session_key(self):
+        """
+        Most session backends don't need to override this method, but we do,
+        because instead of generating a random string, we want to actually
+        generate a secure url-safe Base64-encoded string of data as our
+        session key.
+        """
+        return signing.dumps(getattr(self, '_session_cache', {}),
+            salt='django.contrib.sessions.backends.cookies', compress=True)
diff --git a/django/contrib/sessions/tests.py b/django/contrib/sessions/tests.py
index 2eb43f3..55d69fd 100644
--- a/django/contrib/sessions/tests.py
+++ b/django/contrib/sessions/tests.py
@@ -7,6 +7,7 @@ from django.contrib.sessions.backends.db import SessionStore as DatabaseSession
 from django.contrib.sessions.backends.cache import SessionStore as CacheSession
 from django.contrib.sessions.backends.cached_db import SessionStore as CacheDBSession
 from django.contrib.sessions.backends.file import SessionStore as FileSession
+from django.contrib.sessions.backends.cookies import SessionStore as CookieSession
 from django.contrib.sessions.models import Session
 from django.contrib.sessions.middleware import SessionMiddleware
 from django.core.exceptions import ImproperlyConfigured, SuspiciousOperation
@@ -361,3 +362,15 @@ class SessionMiddlewareTests(unittest.TestCase):
         # Handle the response through the middleware
         response = middleware.process_response(request, response)
         self.assertTrue(response.cookies[settings.SESSION_COOKIE_NAME]['httponly'])
+
+
+class CookieSessionTests(SessionTestsMixin, TestCase):
+
+    backend = CookieSession
+
+    def test_save(self):
+        """
+        This test tested exists() in the other session backends, but that
+        doesn't make sense for us.
+        """
+        pass
diff --git a/docs/topics/http/sessions.txt b/docs/topics/http/sessions.txt
index 8529f53..4632641 100644
--- a/docs/topics/http/sessions.txt
+++ b/docs/topics/http/sessions.txt
@@ -95,6 +95,15 @@ defaults to output from ``tempfile.gettempdir()``, most likely ``/tmp``) to
 control where Django stores session files. Be sure to check that your Web
 server has permissions to read and write to this location.
 
+Using cookies-based sessions
+----------------------------
+
+.. versionadded:: 1.4
+
+To use cookies-based sessions, set the :setting:`SESSION_ENGINE` setting to
+``"django.contrib.sessions.backends.cookies"``. The session data will be
+stored using Django's tools for :doc:`cryptographic signing </topics/signing>`
+and the :setting:`SECRET_KEY` setting.
 
 Using sessions in views
 =======================
@@ -420,6 +429,7 @@ Controls where Django stores session data. Valid values are:
     * ``'django.contrib.sessions.backends.file'``
     * ``'django.contrib.sessions.backends.cache'``
     * ``'django.contrib.sessions.backends.cached_db'``
+    * ``'django.contrib.sessions.backends.cookies'``
 
 See `configuring the session engine`_ for more details.
 
