diff --git a/administrator/components/com_users/models/user.php b/administrator/components/com_users/models/user.php index 795eb8ba2739c..cbb4f67857452 100644 --- a/administrator/components/com_users/models/user.php +++ b/administrator/components/com_users/models/user.php @@ -960,15 +960,50 @@ public function getOtpConfig($user_id = null) } // Get the encrypted data - list($method, $encryptedConfig) = explode(':', $item->otpKey, 2); + list($method, $config) = explode(':', $item->otpKey, 2); $encryptedOtep = $item->otep; - - // Create an encryptor class + + // Get the secret key, yes the thing that is saved in the configuration file $key = $this->getOtpConfigEncryptionKey(); + + if (strpos($config, '{') === false) + { + $openssl = new FOFEncryptAes($key, 256); + $mcrypt = new FOFEncryptAes($key, 256, 'cbc', null, 'mcrypt'); + + $decryptedConfig = $mcrypt->decryptString($config); + + if (strpos($decryptedConfig, '{') !== false) + { + // Data encrypted with mcrypt + $decryptedOtep = $mcrypt->decryptString($encryptedOtep); + $encryptedOtep = $openssl->encryptString($decryptedOtep); + } + else + { + // Config data seems to be save encrypted, this can happen with 3.6.3 and openssl, lets get the data + $decryptedConfig = $openssl->decryptString($config); + } + + $otpKey = $method . ':' . $decryptedConfig; + + $query = $db->getQuery(true) + ->update($db->qn('#__users')) + ->set($db->qn('otep') . '=' . $db->q($encryptedOtep)) + ->set($db->qn('otpKey') . '=' . $db->q($otpKey)) + ->where($db->qn('id') . ' = ' . $db->q($user_id)); + $db->setQuery($query); + $db->execute(); + } + else + { + $decryptedConfig = $config; + } + + // Create an encryptor class $aes = new FOFEncryptAes($key, 256); // Decrypt the data - $decryptedConfig = $aes->decryptString($encryptedConfig); $decryptedOtep = $aes->decryptString($encryptedOtep); // Remove the null padding added during encryption @@ -1008,7 +1043,7 @@ public function getOtpConfig($user_id = null) // Return the configuration object return $otpConfig; } - + /** * Sets the one time password (OTP) – a.k.a. two factor authentication – * configuration for a particular user. The $otpConfig object is the same as @@ -1040,7 +1075,7 @@ public function setOtpConfig($user_id, $otpConfig) { $decryptedConfig = json_encode($otpConfig->config); $decryptedOtep = json_encode($otpConfig->otep); - $updates->otpKey = $otpConfig->method . ':' . $aes->encryptString($decryptedConfig); + $updates->otpKey = $otpConfig->method . ':' . $decryptedConfig; $updates->otep = $aes->encryptString($decryptedOtep); } diff --git a/libraries/fof/encrypt/aes.php b/libraries/fof/encrypt/aes.php index a0d6ede1fb9c5..25c5c06b6c103 100644 --- a/libraries/fof/encrypt/aes.php +++ b/libraries/fof/encrypt/aes.php @@ -22,33 +22,46 @@ class FOFEncryptAes * * @var string */ - private $key = ''; + protected $key = ''; /** * The AES encryption adapter in use. * * @var FOFEncryptAesInterface */ - private $adapter; - + protected $adapter; + /** * Initialise the AES encryption object. * * Note: If the key is not 16 bytes this class will do a stupid key expansion for legacy reasons (produce the * SHA-256 of the key string and throw away half of it). * - * @param string $key The encryption key (password). It can be a raw key (16 bytes) or a passphrase. - * @param int $strength Bit strength (128, 192 or 256) – ALWAYS USE 128 BITS. THIS PARAMETER IS DEPRECATED. - * @param string $mode Encryption mode. Can be ebc or cbc. We recommend using cbc. - * @param FOFUtilsPhpfunc $phpfunc For testing + * @param string $key The encryption key (password). It can be a raw key (16 bytes) or a passphrase. + * @param int $strength Bit strength (128, 192 or 256) – ALWAYS USE 128 BITS. THIS PARAMETER IS DEPRECATED. + * @param string $mode Encryption mode. Can be ebc or cbc. We recommend using cbc. + * @param FOFUtilsPhpfunc $phpfunc For testing + * @param string $priority Priority which adapter we should try first */ - public function __construct($key, $strength = 128, $mode = 'cbc', FOFUtilsPhpfunc $phpfunc = null) + public function __construct($key, $strength = 128, $mode = 'cbc', FOFUtilsPhpfunc $phpfunc = null, $priority = 'openssl') { - $this->adapter = new FOFEncryptAesOpenssl(); - - if (!$this->adapter->isSupported($phpfunc)) + if ($priority == 'openssl') + { + $this->adapter = new FOFEncryptAesOpenssl(); + + if (!$this->adapter->isSupported($phpfunc)) + { + $this->adapter = new FOFEncryptAesMcrypt(); + } + } + else { $this->adapter = new FOFEncryptAesMcrypt(); + + if (!$this->adapter->isSupported($phpfunc)) + { + $this->adapter = new FOFEncryptAesOpenssl(); + } } $this->adapter->setEncryptionMode($mode, $strength);