diff --git a/mongodb_session/mongodb_session.inc b/mongodb_session/mongodb_session.inc
index 785b387..1f0b39f 100644
--- a/mongodb_session/mongodb_session.inc
+++ b/mongodb_session/mongodb_session.inc
@@ -173,6 +173,9 @@ function _drupal_session_write($sid, $value) {
       unset($key['sid']);
     }
   }
+  elseif (variable_get('https', FALSE)) {
+    unset($key['ssid']);
+  }
 
   $collection = mongodb_collection(variable_get('mongodb_session', 'session'));
   $collection
@@ -204,7 +207,7 @@ function _drupal_session_write($sid, $value) {
  * Initialize the session handler, starting a session if needed.
  */
 function drupal_session_initialize() {
-  global $user;
+  global $user, $is_https;
 
   session_set_save_handler('_drupal_session_open', '_drupal_session_close', '_drupal_session_read', '_drupal_session_write', '_drupal_session_destroy', '_drupal_session_garbage_collection');
 
@@ -223,8 +226,17 @@ function drupal_session_initialize() {
     // we lazyly start sessions at the end of this request, and some
     // processes (like drupal_get_token()) needs to know the future
     // session ID in advance.
+    $GLOBALS['lazy_session'] = TRUE;
     $user = drupal_anonymous_user();
+    // Less random sessions (which are much faster to generate) are used for
+    // anonymous users than are generated in drupal_session_regenerate() when
+    // a user becomes authenticated.
     session_id(md5(uniqid('', TRUE)));
+    if ($is_https && variable_get('https', FALSE)) {
+      $insecure_session_name = substr(session_name(), 1);
+      $session_id = drupal_hash_base64(uniqid(mt_rand(), TRUE));
+      $_COOKIE[$insecure_session_name] = $session_id;
+    }
   }
   if (isset($user->timezone)) {
     date_default_timezone_set(drupal_get_user_timezone());
@@ -257,7 +269,7 @@ function drupal_session_start() {
  * If an anonymous user already have an empty session, destroy it.
  */
 function drupal_session_commit() {
-  global $user;
+  global $user, $is_https;
 
   if (!drupal_save_session()) {
     // We don't have anything to do if we are not allowed to save the session.
@@ -276,6 +288,12 @@ function drupal_session_commit() {
     // started.
     if (!drupal_session_started()) {
       drupal_session_start();
+      if ($is_https && variable_get('https', FALSE)) {
+        $insecure_session_name = substr(session_name(), 1);
+        $params = session_get_cookie_params();
+        $expire = $params['lifetime'] ? REQUEST_TIME + $params['lifetime'] : 0;
+        setcookie($insecure_session_name, $_COOKIE[$insecure_session_name], $expire, $params['path'], $params['domain'], FALSE, $params['httponly']);
+      }
     }
     // Write the session data.
     session_write_close();
@@ -302,9 +320,16 @@ function drupal_session_regenerate() {
   global $user, $is_https;
   if ($is_https && variable_get('https', FALSE)) {
     $insecure_session_name = substr(session_name(), 1);
+    if (!isset($GLOBALS['lazy_session']) && isset($_COOKIE[$insecure_session_name])) {
+      $old_insecure_session_id = $_COOKIE[$insecure_session_name];
+    }
     $params = session_get_cookie_params();
-    $session_id = md5(uniqid(mt_rand(), TRUE));
-    setcookie($insecure_session_name, $session_id, REQUEST_TIME + $params['lifetime'], $params['path'], $params['domain'], FALSE, $params['httponly']);
+    $session_id = drupal_hash_base64(uniqid(mt_rand(), TRUE) . drupal_random_bytes(55));
+    // If a session cookie lifetime is set, the session will expire
+    // $params['lifetime'] seconds from the current request. If it is not set,
+    // it will expire when the browser is closed.
+    $expire = $params['lifetime'] ? REQUEST_TIME + $params['lifetime'] : 0;
+    setcookie($insecure_session_name, $session_id, $expire, $params['path'], $params['domain'], FALSE, $params['httponly']);
     $_COOKIE[$insecure_session_name] = $session_id;
   }
 
@@ -353,7 +378,10 @@ function _drupal_session_destroy($sid) {
   // Unset the session cookies.
   _drupal_session_delete_cookie(session_name());
   if ($is_https) {
-    _drupal_session_delete_cookie(substr(session_name(), 1), TRUE);
+    _drupal_session_delete_cookie(substr(session_name(), 1), FALSE);
+  }
+  elseif (variable_get('https', FALSE)) {
+    _drupal_session_delete_cookie('S' . session_name(), TRUE);
   }
 }
 
@@ -362,13 +390,17 @@ function _drupal_session_destroy($sid) {
  *
  * @param sting $name
  *   Name of session cookie to delete.
- * @param boolean $force_insecure
- *   Force cookie to be insecure.
+ * @param boolean $secure
+ *   Force the secure value of the cookie.
  */
-function _drupal_session_delete_cookie($name, $force_insecure = FALSE) {
-  if (isset($_COOKIE[$name])) {
+function _drupal_session_delete_cookie($name, $secure = NULL) {
+  global $is_https;
+  if (isset($_COOKIE[$name]) || (!$is_https && $secure === TRUE)) {
     $params = session_get_cookie_params();
-    setcookie($name, '', REQUEST_TIME - 3600, $params['path'], $params['domain'], !$force_insecure && $params['secure'], $params['httponly']);
+    if ($secure !== NULL) {
+      $params['secure'] = $secure;
+    }
+    setcookie($name, '', REQUEST_TIME - 3600, $params['path'], $params['domain'], $params['secure'], $params['httponly']);
     unset($_COOKIE[$name]);
   }
 }
