diff --git a/lib/Cake/Test/Case/Utility/SecurityTest.php b/lib/Cake/Test/Case/Utility/SecurityTest.php
index 9c67c7680..57e763758 100644
--- a/lib/Cake/Test/Case/Utility/SecurityTest.php
+++ b/lib/Cake/Test/Case/Utility/SecurityTest.php
@@ -256,10 +256,27 @@ class SecurityTest extends CakeTestCase {
 		$result = Security::rijndael('', $key, 'encrypt');
 		$this->assertEquals('', Security::rijndael($result, $key, 'decrypt'));
 
-		$result = Security::rijndael($txt, $key = 'this is my key of over 32 chars, yes it is', 'encrypt');
+		$key = 'this is my key of over 32 chars, yes it is';
+		$result = Security::rijndael($txt, $key, 'encrypt');
 		$this->assertEquals($txt, Security::rijndael($result, $key, 'decrypt'));
 	}
 
+/**
+ * Test that rijndael() can still decrypt values with a fixed iv.
+ *
+ * @return
+ */
+	public function testRijndaelBackwardCompatibility() {
+		$this->skipIf(!function_exists('mcrypt_encrypt'));
+
+		$txt = 'The quick brown fox jumped over the lazy dog.';
+		$key = 'DYhG93b0qyJfIxfs2guVoUubWwvniR2G0FgaC9mi';
+
+		// Encrypted before random iv
+		$value = base64_decode('1WPjnq96LMzLGwNgmudHF+cAIqVUN5DaUZEpf5tm1EzSgt5iYY9o3d66iRI/fKJLTlTVGsa8HzW0jDNitmVXoQ==');
+		$this->assertEquals($txt, Security::rijndael($value, $key, 'decrypt'));
+	}
+
 /**
  * testRijndaelInvalidOperation method
  *
diff --git a/lib/Cake/Utility/Security.php b/lib/Cake/Utility/Security.php
index 324b6bb7d..d871dce3a 100644
--- a/lib/Cake/Utility/Security.php
+++ b/lib/Cake/Utility/Security.php
@@ -198,6 +198,10 @@ class Security {
 /**
  * Encrypts/Decrypts a text using the given key using rijndael method.
  *
+ * Prior to 2.3.1, a fixed initialization vector was used. This was not
+ * secure. This method now uses a random iv, and will silently upgrade values when
+ * they are re-encrypted.
+ *
  * @param string $text Encrypted string to decrypt, normal string to encrypt
  * @param string $key Key to use as the encryption key for encrypted data.
  * @param string $operation Operation to perform, encrypt or decrypt
@@ -218,12 +222,21 @@ class Security {
 		}
 		$algorithm = MCRYPT_RIJNDAEL_256;
 		$mode = MCRYPT_MODE_CBC;
+		$ivSize = mcrypt_get_iv_size($algorithm, $mode);
+
 		$cryptKey = substr($key, 0, 32);
-		$iv = substr($key, strlen($key) - 32, 32);
 
 		if ($operation === 'encrypt') {
-			return mcrypt_encrypt($algorithm, $cryptKey, $text, $mode, $iv);
+			$iv = mcrypt_create_iv($ivSize, MCRYPT_RAND);
+			return $iv . '$$' . mcrypt_encrypt($algorithm, $cryptKey, $text, $mode, $iv);
 		}
+		// Backwards compatible decrypt with fixed iv
+		if (substr($text, $ivSize, 2) !== '$$') {
+			$iv = substr($key, strlen($key) - 32, 32);
+			return rtrim(mcrypt_decrypt($algorithm, $cryptKey, $text, $mode, $iv), "\0");
+		}
+		$iv = substr($text, 0, $ivSize);
+		$text = substr($text, $ivSize + 2);
 		return rtrim(mcrypt_decrypt($algorithm, $cryptKey, $text, $mode, $iv), "\0");
 	}