* @git Joomla Component Builder * @copyright Copyright (C) 2015 Vast Development Method. All rights reserved. * @license GNU General Public License version 2 or later; see LICENSE.txt */ namespace VDM\Joomla\Componentbuilder; use VDM\Joomla\Componentbuilder\Crypt\FOF; use VDM\Joomla\Componentbuilder\Crypt\Aes; use VDM\Joomla\Componentbuilder\Crypt\Aes\Legacy; use VDM\Joomla\Componentbuilder\Crypt\Password; use VDM\Joomla\Componentbuilder\Interfaces\Cryptinterface; use VDM\Joomla\Utilities\StringHelper; /** * Crypto Class * * @since 3.2.0 */ class Crypt { /** * The Crypt AES FOF class * replacement class * * @var FOF * @since 3.2.0 */ protected FOF $fof; /** * The Crypt AES CBC class * * @var Aes * @since 3.2.0 */ protected Aes $aes; /** * The Crypt AES Legacy class * * @var Legacy * @since 3.2.0 */ protected Legacy $legacy; /** * The Password class * * @var Password * @since 3.2.0 */ protected Password $password; /** * Active encryption options * * @var array * @since 3.2.0 */ protected array $options = [ 'basic' => 'fof', 'medium' => 'fof', 'local' => 'aes' ]; /** * Active passwords * * @var array * @since 3.2.0 */ protected array $passwords = []; /** * Constructor * * @param FOF $fof The FOF class * @param Aes $aes The AES CBC class * @param Legacy $legacy The AES Legacy class * @param Password $password The Password class * * @since 3.2.0 */ public function __construct(FOF $fof, Aes $aes, Legacy $legacy, Password $password) { $this->fof = $fof; $this->aes = $aes; $this->legacy = $legacy; $this->password = $password; } /** * Encrypt a string as needed * * @param string $string The string to encrypt * @param string $method The encryption method to use * @param string|null $password The password * * @return string * @since 3.2.0 **/ public function encrypt(string $string, string $method, ?string $password = null): string { if (($password = $this->getPassword($method, $password)) !== null && ($name = $this->getClassName($method)) !== null) { return $this->{$name}->encrypt($string, $password); } return $string; } /** * Decrypt a string as needed * * @param string $string The string to decrypt * @param string $method The encryption method to use * @param string|null $default The default password * * @return string|null * @since 3.2.0 **/ public function decrypt(string $string, string $method, ?string $default = null): ?string { if (($password = $this->getPassword($method, $default)) !== null && ($name = $this->getClassName($method)) !== null) { return $this->{$name}->decrypt($string, $password); } return null; } /** * Check if a decryption method exist and is supported * * @param string $method The encryption method to find * * @return bool true if it exist * @since 3.2.0 **/ public function exist(string $method): bool { return is_string($this->getClassName($method)) ?? false; } /** * Get crypto class name to use * * @param string $method The encryption method to find * * @return string|null The crypto class name * @since 3.2.0 **/ private function getClassName(string $method): ?string { if (($name = $this->getClassNameFromRegistry($method)) !== null) { return $name; } return $this->getClassNameFromOptions($method); } /** * Get the crypto class name from the registry * * @param string $method The encryption method to use * * @return string|null The crypto class name, or null if not found * @since 3.2.0 **/ private function getClassNameFromRegistry(string $method): ?string { $name = $this->name($method); if (isset($this->{$name}) && $this->{$name} instanceof Cryptinterface) { return $name; } return null; } /** * Get the crypto class name for the given encryption method and options * * @param string $method The encryption method to use * * @return string|null The crypto class name, or null if not found * @since 3.2.0 **/ private function getClassNameFromOptions(string $method): ?string { $key = $this->getPasswordKey($method); if (isset($this->options[$key])) { $name = $this->options[$key]; if (isset($this->{$name}) && $this->{$name} instanceof Cryptinterface) { return $name; } } return null; } /** * Get the password * * @param string $method The encryption method to find * @param string|null $password The password * * @return string|null the password or null * @since 3.2.0 **/ private function getPassword(string $method, ?string $password = null): ?string { if (StringHelper::check($password)) { return $password; } // get password key name $key = $this->getPasswordKey($method); if (empty($this->passwords[$key])) { $this->passwords[$key] = $this->password->get($key); } return $this->passwords[$key]; } /** * Get the key * * @param string $method The encryption method to find * * @return string the password key name * @since 3.2.0 **/ private function getPasswordKey(string $method): string { if (($pos = strpos($method, '.')) !== false) { return substr($method, 0, $pos); } return $method; } /** * Get the class name * * @param string $method The encryption method to find * * @return string the class name * @since 3.2.0 **/ private function name(string $method): string { if (($pos = strpos($method, '.')) !== false) { return substr($method, $pos + 1); } return $method; } }