From 491c426623ff8a4f3f99078801412ed155cb168a Mon Sep 17 00:00:00 2001 From: Robert Scheck Date: Wed, 19 Nov 2014 07:38:32 -0500 Subject: [PATCH 1/2] Patch by Robert Scheck for phpMyAdmin 4.2.6 which enhances cookie encryption/decryption by the optional usage of PHP OpenSSL. Unfortunately PHP Mcrypt is not shipped by all Linux distributions however PHP OpenSSL is often enabled by default. PHP < 5.3.4 does not support passing an IV, thus this has been added as a requirement. I could have used 'BF-CBC' rather 'AES-128-CBC' but Blowfish (even it is fast) is seen by experts as weaker algorithm than AES. If this should be a show-stopper for upstream merging just replace 'AES-128-CBC' by 'BF-CBC', please. Patch adapted for 4.3.x and tests modified by Marc Delisle Signed-off-by: Marc Delisle --- .../auth/AuthenticationCookie.class.php | 57 ++++++++++++++----- .../auth/PMA_AuthenticationCookie_test.php | 20 ++++--- 2 files changed, 54 insertions(+), 23 deletions(-) diff --git a/libraries/plugins/auth/AuthenticationCookie.class.php b/libraries/plugins/auth/AuthenticationCookie.class.php index d21c510f43..79015f8174 100644 --- a/libraries/plugins/auth/AuthenticationCookie.class.php +++ b/libraries/plugins/auth/AuthenticationCookie.class.php @@ -727,8 +727,8 @@ class AuthenticationCookie extends AuthenticationPlugin } /** - * Encryption using phpseclib's AES - * (it uses mcrypt when it is available) + * Encryption using openssl's AES or phpseclib's AES + * (phpseclib uses mcrypt when it is available) * * @param string $data original data * @param string $secret the secret @@ -737,15 +737,25 @@ class AuthenticationCookie extends AuthenticationPlugin */ public function cookieEncrypt($data, $secret) { - $cipher = new Crypt_AES(CRYPT_AES_MODE_CBC); - $cipher->setIV($this->_cookie_iv); - $cipher->setKey($secret); - return base64_encode($cipher->encrypt($data)); + if (function_exists('openssl_encrypt') && PHP_VERSION_ID >= 50304) { + return openssl_encrypt( + $data, + 'AES-128-CBC', + $secret, + 0, + $this->_cookie_iv + ); + } else { + $cipher = new Crypt_AES(CRYPT_AES_MODE_CBC); + $cipher->setIV($this->_cookie_iv); + $cipher->setKey($secret); + return base64_encode($cipher->encrypt($data)); + } } /** - * Decryption using phpseclib's AES - * (it uses mcrypt when it is available) + * Decryption using openssl's AES or phpseclib's AES + * (phpseclib uses mcrypt when it is available) * * @param string $encdata encrypted data * @param string $secret the secret @@ -758,10 +768,23 @@ class AuthenticationCookie extends AuthenticationPlugin $this->_cookie_iv = base64_decode($_COOKIE['pma_iv'], true); } - $cipher = new Crypt_AES(CRYPT_AES_MODE_CBC); - $cipher->setIV($this->_cookie_iv); - $cipher->setKey($secret); - return $cipher->decrypt(base64_decode($encdata)); + if (function_exists('openssl_decrypt') && PHP_VERSION_ID >= 50304) { + if (strlen($this->_cookie_iv) < openssl_cipher_iv_length('AES-128-CBC')) { + $this->createIV(); + } + return openssl_decrypt( + $encdata, + 'AES-128-CBC', + $secret, + 0, + $this->_cookie_iv + ); + } else { + $cipher = new Crypt_AES(CRYPT_AES_MODE_CBC); + $cipher->setIV($this->_cookie_iv); + $cipher->setKey($secret); + return $cipher->decrypt(base64_decode($encdata)); + } } /** @@ -774,8 +797,14 @@ class AuthenticationCookie extends AuthenticationPlugin */ public function createIV() { - $cipher = new Crypt_AES(CRYPT_AES_MODE_CBC); - $this->_cookie_iv = crypt_random_string($cipher->block_size); + if (function_exists('openssl_encrypt') && PHP_VERSION_ID >= 50304) { + $this->_cookie_iv = openssl_random_pseudo_bytes( + openssl_cipher_iv_length('AES-128-CBC') + ); + } else { + $cipher = new Crypt_AES(CRYPT_AES_MODE_CBC); + $this->_cookie_iv = crypt_random_string($cipher->block_size); + } $GLOBALS['PMA_Config']->setCookie( 'pma_iv', base64_encode($this->_cookie_iv) diff --git a/test/classes/plugin/auth/PMA_AuthenticationCookie_test.php b/test/classes/plugin/auth/PMA_AuthenticationCookie_test.php index 706dc2556c..9e083be876 100644 --- a/test/classes/plugin/auth/PMA_AuthenticationCookie_test.php +++ b/test/classes/plugin/auth/PMA_AuthenticationCookie_test.php @@ -568,7 +568,7 @@ class PMA_AuthenticationCookie_Test extends PHPUnit_Framework_TestCase $GLOBALS['server'] = 1; $_COOKIE['pmaServer-1'] = 'pmaServ1'; $_COOKIE['pmaUser-1'] = ''; - $_COOKIE['pma_iv'] = base64_encode('testiv09'); + $_COOKIE['pma_iv'] = base64_encode('testiv09testiv09'); $this->assertFalse( $this->object->authCheck() @@ -584,7 +584,7 @@ class PMA_AuthenticationCookie_Test extends PHPUnit_Framework_TestCase $GLOBALS['server'] = 1; $_COOKIE['pmaServer-1'] = 'pmaServ1'; $_COOKIE['pmaUser-1'] = 'pmaUser1'; - $_COOKIE['pma_iv'] = base64_encode('testiv09'); + $_COOKIE['pma_iv'] = base64_encode('testiv09testiv09'); $_COOKIE['pmaPass-1'] = ''; $GLOBALS['cfg']['blowfish_secret'] = 'secret'; $_SESSION['last_access_time'] = time() - 1000; @@ -659,7 +659,7 @@ class PMA_AuthenticationCookie_Test extends PHPUnit_Framework_TestCase $_REQUEST['pma_username'] = ''; $_COOKIE['pmaServer-1'] = 'pmaServ1'; $_COOKIE['pmaUser-1'] = 'pmaUser1'; - $_COOKIE['pma_iv'] = base64_encode('testiv09'); + $_COOKIE['pma_iv'] = base64_encode('testiv09testiv09'); $GLOBALS['cfg']['blowfish_secret'] = 'secret'; $_SESSION['last_access_time'] = ''; $_SESSION['last_valid_captcha'] = true; @@ -698,7 +698,7 @@ class PMA_AuthenticationCookie_Test extends PHPUnit_Framework_TestCase $_COOKIE['pmaServer-1'] = 'pmaServ1'; $_COOKIE['pmaUser-1'] = 'pmaUser1'; $_COOKIE['pmaPass-1'] = 'pmaPass1'; - $_COOKIE['pma_iv'] = base64_encode('testiv09'); + $_COOKIE['pma_iv'] = base64_encode('testiv09testiv09'); $GLOBALS['cfg']['blowfish_secret'] = 'secret'; $_SESSION['last_valid_captcha'] = true; $_SESSION['last_access_time'] = time() - 1000; @@ -742,7 +742,7 @@ class PMA_AuthenticationCookie_Test extends PHPUnit_Framework_TestCase $_REQUEST['pma_username'] = ''; $_COOKIE['pmaServer-1'] = 'pmaServ1'; $_COOKIE['pmaUser-1'] = 'pmaUser1'; - $_COOKIE['pma_iv'] = base64_encode('testiv09'); + $_COOKIE['pma_iv'] = base64_encode('testiv09testiv09'); $GLOBALS['cfg']['blowfish_secret'] = 'secret'; $_SESSION['last_access_time'] = 1; $_SESSION['last_valid_captcha'] = true; @@ -1049,9 +1049,10 @@ class PMA_AuthenticationCookie_Test extends PHPUnit_Framework_TestCase */ public function testCookieEncrypt() { - $this->object->setIV('testiv09'); + $this->object->setIV('testiv09testiv09'); + // works with the openssl extension active or inactive $this->assertEquals( - 'vzJVtW8Ujd4phw7Cxl2PcQ==', + '+coP/up/ZBTBwbiEpCUVXQ==', $this->object->cookieEncrypt('data123', 'sec321') ); } @@ -1063,11 +1064,12 @@ class PMA_AuthenticationCookie_Test extends PHPUnit_Framework_TestCase */ public function testCookieDecrypt() { - $this->object->setIV('testiv09'); + $this->object->setIV('testiv09testiv09'); + // works with the openssl extension active or inactive $this->assertEquals( 'data123', $this->object->cookieDecrypt( - 'vzJVtW8Ujd4phw7Cxl2PcQ==', + '+coP/up/ZBTBwbiEpCUVXQ==', 'sec321' ) ); From d067ae7dd5f4cf58597f4a5182c0f7fa6a1cb0f5 Mon Sep 17 00:00:00 2001 From: Marc Delisle Date: Wed, 19 Nov 2014 07:43:09 -0500 Subject: [PATCH 2/2] ChangeLog entry Signed-off-by: Marc Delisle --- ChangeLog | 1 + 1 file changed, 1 insertion(+) diff --git a/ChangeLog b/ChangeLog index c2509e1f81..e920419d35 100644 --- a/ChangeLog +++ b/ChangeLog @@ -63,6 +63,7 @@ phpMyAdmin - ChangeLog - bug #4513 phpmyadmin run very slow (information_schema) - bug #4243 Super slow page rendering with tens of thousands of DBs - bug #4391 Upgraded to 4.2.0, insanely slow now ++ rfe #1537 PHP OpenSSL support for cookie encryption/decryption 4.2.12.0 (not yet released) - bug #4574 Blank/white page when JavaScript disabled