File manager - Edit - /home/opticamezl/www/newok/Encrypt.tar
Back
Totp.php 0000644 00000013702 15173005011 0006177 0 ustar 00 <?php /** * Joomla! Content Management System * * @copyright (C) 2013 Open Source Matters, Inc. <https://www.joomla.org> * @license GNU General Public License version 2 or later; see LICENSE.txt * @note This file has been modified by the Joomla! Project and no longer reflects the original work of its author. */ namespace Joomla\CMS\Encrypt; // phpcs:disable PSR1.Files.SideEffects \defined('JPATH_PLATFORM') or die; // phpcs:enable PSR1.Files.SideEffects /** * This class provides an RFC6238-compliant Time-based One Time Passwords, * compatible with Google Authenticator (with PassCodeLength = 6 and TimePeriod = 30). * * @since 4.0.0 */ class Totp { /** * Passcode length * * @var integer */ private $_passCodeLength = 6; /** * Pin modulo * * @var integer */ private $_pinModulo; /** * The length of the secret in bytes. * RFC 4226: "The length of the shared secret MUST be at least 128 bits. This document RECOMMENDs a shared secret length of 160 bits." * The original value was 10 bytes (80 bits) this value has been increased to 20 (160 bits) with Joomla! 3.9.25 * * @var integer */ private $_secretLength = 20; /** * Timestep * * @var integer */ private $_timeStep = 30; /** * Base32 * * @var integer */ private $_base32 = null; /** * Initialises an RFC6238-compatible TOTP generator. Please note that this * class does not implement the constraint in the last paragraph of §5.2 * of RFC6238. It's up to you to ensure that the same user/device does not * retry validation within the same Time Step. * * @param int $timeStep The Time Step (in seconds). Use 30 to be compatible with Google Authenticator. * @param int $passCodeLength The generated passcode length. Default: 6 digits. * @param int $secretLength The length of the secret key. Default: 10 bytes (80 bits). * @param Object $base32 The base32 en/decrypter */ public function __construct($timeStep = 30, $passCodeLength = 6, $secretLength = 10, $base32 = null) { $this->_timeStep = $timeStep; $this->_passCodeLength = $passCodeLength; $this->_secretLength = $secretLength; $this->_pinModulo = pow(10, $this->_passCodeLength); if (\is_null($base32)) { $this->_base32 = new Base32(); } else { $this->_base32 = $base32; } } /** * Get the time period based on the $time timestamp and the Time Step * defined. If $time is skipped or set to null the current timestamp will * be used. * * @param int|null $time Timestamp * * @return integer The time period since the UNIX Epoch */ public function getPeriod($time = null) { if (\is_null($time)) { $time = time(); } $period = floor($time / $this->_timeStep); return $period; } /** * Check is the given passcode $code is a valid TOTP generated using secret * key $secret * * @param string $secret The Base32-encoded secret key * @param string $code The passcode to check * * @return boolean True if the code is valid */ public function checkCode($secret, $code) { $time = $this->getPeriod(); for ($i = -1; $i <= 1; $i++) { if ($this->getCode($secret, ($time + $i) * $this->_timeStep) == $code) { return true; } } return false; } /** * Gets the TOTP passcode for a given secret key $secret and a given UNIX * timestamp $time * * @param string $secret The Base32-encoded secret key * @param int $time UNIX timestamp * * @return string */ public function getCode($secret, $time = null) { $period = $this->getPeriod($time); $secret = $this->_base32->decode($secret); $time = pack("N", $period); $time = str_pad($time, 8, \chr(0), STR_PAD_LEFT); $hash = hash_hmac('sha1', $time, $secret, true); $offset = \ord(substr($hash, -1)); $offset = $offset & 0xF; $truncatedHash = $this->hashToInt($hash, $offset) & 0x7FFFFFFF; $pinValue = str_pad($truncatedHash % $this->_pinModulo, $this->_passCodeLength, "0", STR_PAD_LEFT); return $pinValue; } /** * Extracts a part of a hash as an integer * * @param string $bytes The hash * @param string $start The char to start from (0 = first char) * * @return string */ protected function hashToInt($bytes, $start) { $input = substr($bytes, $start, \strlen($bytes) - $start); $val2 = unpack("N", substr($input, 0, 4)); return $val2[1]; } /** * Returns a QR code URL for easy setup of TOTP apps like Google Authenticator * * @param string $user User * @param string $hostname Hostname * @param string $secret Secret string * * @return string */ public function getUrl($user, $hostname, $secret) { $url = sprintf("otpauth://totp/%s@%s?secret=%s", $user, $hostname, $secret); $encoder = "https://chart.googleapis.com/chart?chs=200x200&chld=Q|2&cht=qr&chl="; $encoderURL = $encoder . urlencode($url); return $encoderURL; } /** * Generates a (semi-)random Secret Key for TOTP generation * * @return string * * @note Since 3.9.25 we use the secure method "random_bytes" over the original insecure "rand" function. * The random_bytes function has been backported to outdated PHP versions by the core shipped library paragonie/random_compat */ public function generateSecret() { $secret = random_bytes($this->_secretLength); return $this->_base32->encode($secret); } } Randval.php 0000644 00000001701 15173005011 0006634 0 ustar 00 <?php /** * Joomla! Content Management System * * @copyright (C) 2016 Open Source Matters, Inc. <https://www.joomla.org> * @license GNU General Public License version 2 or later; see LICENSE.txt */ namespace Joomla\CMS\Encrypt; // phpcs:disable PSR1.Files.SideEffects \defined('JPATH_PLATFORM') or die; // phpcs:enable PSR1.Files.SideEffects /** * Generates cryptographically-secure random values. * * @since 4.0.0 */ class Randval implements RandValInterface { /** * Returns a cryptographically secure random value. * * This method allows us to quickly address any future issues if we ever find problems with PHP's random_bytes() on * some weird host (you can't be too careful when releasing mass-distributed software). * * @param integer $bytes How many bytes to return * * @return string */ public function generate($bytes = 32) { return random_bytes($bytes); } } Base32.php 0000644 00000012461 15173005011 0006271 0 ustar 00 <?php /** * Joomla! Content Management System * * @copyright (C) 2013 Open Source Matters, Inc. <https://www.joomla.org> * @license GNU General Public License version 2 or later; see LICENSE.txt */ namespace Joomla\CMS\Encrypt; // phpcs:disable PSR1.Files.SideEffects \defined('JPATH_PLATFORM') or die; // phpcs:enable PSR1.Files.SideEffects /** * Base32 encryption class * * @since 1.0 */ class Base32 { /** * CSRFC3548 * * The character set as defined by RFC3548 * @link http://www.ietf.org/rfc/rfc3548.txt */ public const CSRFC3548 = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ234567'; /** * str2bin * * Converts any ascii string to a binary string * * @param string $str The string you want to convert * * @return string String of 0's and 1's */ private function str2bin($str) { $chrs = unpack('C*', $str); return vsprintf(str_repeat('%08b', \count($chrs)), $chrs); } /** * bin2str * * Converts a binary string to an ascii string * * @param string $str The string of 0's and 1's you want to convert * * @return string The ascii output * * @throws \Exception */ private function bin2str($str) { if (\strlen($str) % 8 > 0) { throw new \Exception('Length must be divisible by 8'); } if (!preg_match('/^[01]+$/', $str)) { throw new \Exception('Only 0\'s and 1\'s are permitted'); } preg_match_all('/.{8}/', $str, $chrs); $chrs = array_map('bindec', $chrs[0]); // I'm just being slack here array_unshift($chrs, 'C*'); return \call_user_func_array('pack', $chrs); } /** * fromBin * * Converts a correct binary string to base32 * * @param string $str The string of 0's and 1's you want to convert * * @return string String encoded as base32 * * @throws \Exception */ private function fromBin($str) { if (\strlen($str) % 8 > 0) { throw new \Exception('Length must be divisible by 8'); } if (!preg_match('/^[01]+$/', $str)) { throw new \Exception('Only 0\'s and 1\'s are permitted'); } // Base32 works on the first 5 bits of a byte, so we insert blanks to pad it out $str = preg_replace('/(.{5})/', '000$1', $str); // We need a string divisible by 5 $length = \strlen($str); $rbits = $length & 7; if ($rbits > 0) { // Excessive bits need to be padded $ebits = substr($str, $length - $rbits); $str = substr($str, 0, $length - $rbits); $str .= "000$ebits" . str_repeat('0', 5 - \strlen($ebits)); } preg_match_all('/.{8}/', $str, $chrs); $chrs = array_map([$this, '_mapcharset'], $chrs[0]); return implode('', $chrs); } /** * toBin * * Accepts a base32 string and returns an ascii binary string * * @param string $str The base32 string to convert * * @return string Ascii binary string * * @throws \Exception */ private function toBin($str) { if (!preg_match('/^[' . self::CSRFC3548 . ']+$/', $str)) { throw new \Exception('Must match character set'); } // Convert the base32 string back to a binary string $str = implode('', array_map([$this, '_mapbin'], str_split($str))); // Remove the extra 0's we added $str = preg_replace('/000(.{5})/', '$1', $str); // Unpad if necessary $length = \strlen($str); $rbits = $length & 7; if ($rbits > 0) { $str = substr($str, 0, $length - $rbits); } return $str; } /** * fromString * * Convert any string to a base32 string * This should be binary safe... * * @param string $str The string to convert * * @return string The converted base32 string */ public function encode($str) { return $this->fromBin($this->str2bin($str)); } /** * toString * * Convert any base32 string to a normal sctring * This should be binary safe... * * @param string $str The base32 string to convert * * @return string The normal string */ public function decode($str) { $str = strtoupper($str); return $this->bin2str($this->toBin($str)); } /** * _mapcharset * * Used with array_map to map the bits from a binary string * directly into a base32 character set * * @param string $str The string of 0's and 1's you want to convert * * @return string Resulting base32 character * * @access private */ private function _mapcharset($str) { // Huh! $x = self::CSRFC3548; return $x[bindec($str)]; } /** * _mapbin * * Used with array_map to map the characters from a base32 * character set directly into a binary string * * @param string $chr The character to map * * @return string String of 0's and 1's * * @access private */ private function _mapbin($chr) { return sprintf('%08b', strpos(self::CSRFC3548, $chr)); } } AES/OpenSSL.php 0000644 00000015260 15173005011 0007145 0 ustar 00 <?php /** * Joomla! Content Management System * * @copyright (C) 2016 Open Source Matters, Inc. <https://www.joomla.org> * @license GNU General Public License version 2 or later; see LICENSE.txt */ namespace Joomla\CMS\Encrypt\AES; use Joomla\CMS\Encrypt\Randval; // phpcs:disable PSR1.Files.SideEffects \defined('JPATH_PLATFORM') or die; // phpcs:enable PSR1.Files.SideEffects /** * OpenSSL encryption class * * @since 4.0.0 */ class OpenSSL extends AbstractAES implements AesInterface { /** * The OpenSSL options for encryption / decryption * * @var integer */ protected $openSSLOptions = 0; /** * The encryption method to use * * @var string */ protected $method = 'aes-128-cbc'; /** * Constructor for this class */ public function __construct() { $this->openSSLOptions = OPENSSL_RAW_DATA | OPENSSL_ZERO_PADDING; } /** * Sets the AES encryption mode. * * WARNING: The strength is deprecated as it has a different effect in MCrypt and OpenSSL. MCrypt was abandoned in * 2003 before the Rijndael-128 algorithm was officially the Advanced Encryption Standard (AES). MCrypt also offered * Rijndael-192 and Rijndael-256 algorithms with different block sizes. These are NOT used in AES. OpenSSL, however, * implements AES correctly. It always uses a 128-bit (16 byte) block. The 192 and 256 bit strengths refer to the * key size, not the block size. Therefore using different strengths in MCrypt and OpenSSL will result in different * and incompatible ciphertexts. * * TL;DR: Always use $strength = 128! * * @param string $mode Choose between CBC (recommended) or ECB * @param int $strength Bit strength of the key (128, 192 or 256 bits). DEPRECATED. READ NOTES ABOVE. * * @return void */ public function setEncryptionMode($mode = 'cbc', $strength = 128) { static $availableAlgorithms = null; static $defaultAlgo = 'aes-128-cbc'; if (!\is_array($availableAlgorithms)) { $availableAlgorithms = openssl_get_cipher_methods(); foreach ( ['aes-256-cbc', 'aes-256-ecb', 'aes-192-cbc', 'aes-192-ecb', 'aes-128-cbc', 'aes-128-ecb', ] as $algo ) { if (\in_array($algo, $availableAlgorithms)) { $defaultAlgo = $algo; break; } } } $strength = (int) $strength; $mode = strtolower($mode); if (!\in_array($strength, [128, 192, 256])) { $strength = 256; } if (!\in_array($mode, ['cbc', 'ebc'])) { $mode = 'cbc'; } $algo = 'aes-' . $strength . '-' . $mode; if (!\in_array($algo, $availableAlgorithms)) { $algo = $defaultAlgo; } $this->method = $algo; } /** * Encrypts a string. Returns the raw binary ciphertext. * * WARNING: The plaintext is zero-padded to the algorithm's block size. You are advised to store the size of the * plaintext and trim the string to that length upon decryption. * * @param string $plainText The plaintext to encrypt * @param string $key The raw binary key (will be zero-padded or chopped if its size is different than the block size) * @param null|string $iv The initialization vector (for CBC mode algorithms) * * @return string The raw encrypted binary string. */ public function encrypt($plainText, $key, $iv = null) { $iv_size = $this->getBlockSize(); $key = $this->resizeKey($key, $iv_size); $iv = $this->resizeKey($iv, $iv_size); if (empty($iv)) { $randVal = new Randval(); $iv = $randVal->generate($iv_size); } $plainText .= $this->getZeroPadding($plainText, $iv_size); $cipherText = openssl_encrypt($plainText, $this->method, $key, $this->openSSLOptions, $iv); $cipherText = $iv . $cipherText; return $cipherText; } /** * Decrypts a string. Returns the raw binary plaintext. * * $ciphertext MUST start with the IV followed by the ciphertext, even for EBC data (the first block of data is * dropped in EBC mode since there is no concept of IV in EBC). * * WARNING: The returned plaintext is zero-padded to the algorithm's block size during encryption. You are advised * to trim the string to the original plaintext's length upon decryption. While rtrim($decrypted, "\0") sounds * appealing it's NOT the correct approach for binary data (zero bytes may actually be part of your plaintext, not * just padding!). * * @param string $cipherText The ciphertext to encrypt * @param string $key The raw binary key (will be zero-padded or chopped if its size is different than the block size) * * @return string The raw unencrypted binary string. */ public function decrypt($cipherText, $key) { $iv_size = $this->getBlockSize(); $key = $this->resizeKey($key, $iv_size); $iv = substr($cipherText, 0, $iv_size); $cipherText = substr($cipherText, $iv_size); $plainText = openssl_decrypt($cipherText, $this->method, $key, $this->openSSLOptions, $iv); // Remove the zero padding return rtrim($plainText, "\0"); } /** * Is this adapter supported? * * @return boolean */ public function isSupported() { if (!\function_exists('openssl_get_cipher_methods')) { return false; } if (!\function_exists('openssl_random_pseudo_bytes')) { return false; } if (!\function_exists('openssl_cipher_iv_length')) { return false; } if (!\function_exists('openssl_encrypt')) { return false; } if (!\function_exists('openssl_decrypt')) { return false; } if (!\function_exists('hash')) { return false; } if (!\function_exists('hash_algos')) { return false; } $algorithms = openssl_get_cipher_methods(); if (!\in_array('aes-128-cbc', $algorithms)) { return false; } $algorithms = hash_algos(); if (!\in_array('sha256', $algorithms)) { return false; } return true; } /** * Returns the encryption block size in bytes * * @return integer */ public function getBlockSize() { return openssl_cipher_iv_length($this->method); } } AES/AesInterface.php 0000644 00000006527 15173005011 0010221 0 ustar 00 <?php /** * Joomla! Content Management System * * @copyright (C) 2016 Open Source Matters, Inc. <https://www.joomla.org> * @license GNU General Public License version 2 or later; see LICENSE.txt */ namespace Joomla\CMS\Encrypt\AES; // phpcs:disable PSR1.Files.SideEffects \defined('JPATH_PLATFORM') or die; // phpcs:enable PSR1.Files.SideEffects /** * Interface for AES encryption adapters * * @since 4.0.0 */ interface AesInterface { /** * Sets the AES encryption mode. * * WARNING: The strength is deprecated as it has a different effect in MCrypt and OpenSSL. MCrypt was abandoned in * 2003 before the Rijndael-128 algorithm was officially the Advanced Encryption Standard (AES). MCrypt also offered * Rijndael-192 and Rijndael-256 algorithms with different block sizes. These are NOT used in AES. OpenSSL, however, * implements AES correctly. It always uses a 128-bit (16 byte) block. The 192 and 256 bit strengths refer to the * key size, not the block size. Therefore using different strengths in MCrypt and OpenSSL will result in different * and incompatible ciphertexts. * * TL;DR: Always use $strength = 128! * * @param string $mode Choose between CBC (recommended) or ECB * @param int $strength Bit strength of the key (128, 192 or 256 bits). DEPRECATED. READ NOTES ABOVE. * * @return mixed */ public function setEncryptionMode($mode = 'cbc', $strength = 128); /** * Encrypts a string. Returns the raw binary ciphertext. * * WARNING: The plaintext is zero-padded to the algorithm's block size. You are advised to store the size of the * plaintext and trim the string to that length upon decryption. * * @param string $plainText The plaintext to encrypt * @param string $key The raw binary key (will be zero-padded or chopped if its size is different than the block size) * @param null|string $iv The initialization vector (for CBC mode algorithms) * * @return string The raw encrypted binary string. */ public function encrypt($plainText, $key, $iv = null); /** * Decrypts a string. Returns the raw binary plaintext. * * $ciphertext MUST start with the IV followed by the ciphertext, even for EBC data (the first block of data is * dropped in EBC mode since there is no concept of IV in EBC). * * WARNING: The returned plaintext is zero-padded to the algorithm's block size during encryption. You are advised * to trim the string to the original plaintext's length upon decryption. While rtrim($decrypted, "\0") sounds * appealing it's NOT the correct approach for binary data (zero bytes may actually be part of your plaintext, not * just padding!). * * @param string $cipherText The ciphertext to encrypt * @param string $key The raw binary key (will be zero-padded or chopped if its size is different than the block size) * * @return string The raw unencrypted binary string. */ public function decrypt($cipherText, $key); /** * Returns the encryption block size in bytes * * @return integer */ public function getBlockSize(); /** * Is this adapter supported? * * @return boolean */ public function isSupported(); } AES/Mcrypt.php 0000644 00000011033 15173005011 0007132 0 ustar 00 <?php /** * Joomla! Content Management System * * @copyright (C) 2016 Open Source Matters, Inc. <https://www.joomla.org> * @license GNU General Public License version 2 or later; see LICENSE.txt */ namespace Joomla\CMS\Encrypt\AES; use Joomla\CMS\Encrypt\Randval; // phpcs:disable PSR1.Files.SideEffects \defined('JPATH_PLATFORM') or die; // phpcs:enable PSR1.Files.SideEffects /** * Mcrypt implementation * * @since 4.0.0 * * @deprecated 4.3 will be removed in 6.0 * Will be removed without replacement */ class Mcrypt extends AbstractAES implements AesInterface { /** * Cypher Type * * @var string */ protected $cipherType = MCRYPT_RIJNDAEL_128; /** * Cypher Mode * * @var string */ protected $cipherMode = MCRYPT_MODE_CBC; /** * Set the encryption mode * * @param string $mode Encryption Mode * @param integer $strength Encryption Strength * * @return void */ public function setEncryptionMode($mode = 'cbc', $strength = 128) { switch ((int) $strength) { default: case '128': $this->cipherType = MCRYPT_RIJNDAEL_128; break; case '192': $this->cipherType = MCRYPT_RIJNDAEL_192; break; case '256': $this->cipherType = MCRYPT_RIJNDAEL_256; break; } switch (strtolower($mode)) { case 'ecb': $this->cipherMode = MCRYPT_MODE_ECB; break; default: case 'cbc': $this->cipherMode = MCRYPT_MODE_CBC; break; } } /** * Encrypt the data * * @param string $plainText Plaintext data * @param string $key Encryption key * @param string $iv IV for the encryption * * @return string Encrypted data */ public function encrypt($plainText, $key, $iv = null) { $iv_size = $this->getBlockSize(); $key = $this->resizeKey($key, $iv_size); $iv = $this->resizeKey($iv, $iv_size); if (empty($iv)) { $randVal = new Randval(); $iv = $randVal->generate($iv_size); } $cipherText = mcrypt_encrypt($this->cipherType, $key, $plainText, $this->cipherMode, $iv); $cipherText = $iv . $cipherText; return $cipherText; } /** * Decrypt encrypted data * * @param string $cipherText Encrypted data * @param string $key Encryptionkey * * @return string Plaintext data */ public function decrypt($cipherText, $key) { $iv_size = $this->getBlockSize(); $key = $this->resizeKey($key, $iv_size); $iv = substr($cipherText, 0, $iv_size); $cipherText = substr($cipherText, $iv_size); $plainText = mcrypt_decrypt($this->cipherType, $key, $cipherText, $this->cipherMode, $iv); return $plainText; } /** * Is this adapter supported? * * @return boolean */ public function isSupported() { if (!\function_exists('mcrypt_get_key_size')) { return false; } if (!\function_exists('mcrypt_get_iv_size')) { return false; } if (!\function_exists('mcrypt_create_iv')) { return false; } if (!\function_exists('mcrypt_encrypt')) { return false; } if (!\function_exists('mcrypt_decrypt')) { return false; } if (!\function_exists('mcrypt_list_algorithms')) { return false; } if (!\function_exists('hash')) { return false; } if (!\function_exists('hash_algos')) { return false; } $algorigthms = mcrypt_list_algorithms(); if (!\in_array('rijndael-128', $algorigthms)) { return false; } if (!\in_array('rijndael-192', $algorigthms)) { return false; } if (!\in_array('rijndael-256', $algorigthms)) { return false; } $algorigthms = hash_algos(); if (!\in_array('sha256', $algorigthms)) { return false; } return true; } /** * Get the block size * * @return integer */ public function getBlockSize() { return mcrypt_get_iv_size($this->cipherType, $this->cipherMode); } } AES/AbstractAES.php 0000644 00000004264 15173005011 0007760 0 ustar 00 <?php /** * Joomla! Content Management System * * @copyright (C) 2016 Open Source Matters, Inc. <https://www.joomla.org> * @license GNU General Public License version 2 or later; see LICENSE.txt */ namespace Joomla\CMS\Encrypt\AES; // phpcs:disable PSR1.Files.SideEffects \defined('JPATH_PLATFORM') or die; // phpcs:enable PSR1.Files.SideEffects /** * Abstract AES encryption class * * @since 4.0.0 */ abstract class AbstractAES { /** * Trims or zero-pads a key / IV * * @param string $key The key or IV to treat * @param int $size The block size of the currently used algorithm * * @return null|string Null if $key is null, treated string of $size byte length otherwise */ public function resizeKey($key, $size) { if (empty($key)) { return null; } $keyLength = \strlen($key); if (\function_exists('mb_strlen')) { $keyLength = mb_strlen($key, 'ASCII'); } if ($keyLength == $size) { return $key; } if ($keyLength > $size) { if (\function_exists('mb_substr')) { return mb_substr($key, 0, $size, 'ASCII'); } return substr($key, 0, $size); } return $key . str_repeat("\0", ($size - $keyLength)); } /** * Returns null bytes to append to the string so that it's zero padded to the specified block size * * @param string $string The binary string which will be zero padded * @param int $blockSize The block size * * @return string The zero bytes to append to the string to zero pad it to $blockSize */ protected function getZeroPadding($string, $blockSize) { $stringSize = \strlen($string); if (\function_exists('mb_strlen')) { $stringSize = mb_strlen($string, 'ASCII'); } if ($stringSize == $blockSize) { return ''; } if ($stringSize < $blockSize) { return str_repeat("\0", $blockSize - $stringSize); } $paddingBytes = $stringSize % $blockSize; return str_repeat("\0", $blockSize - $paddingBytes); } } Aes.php 0000644 00000021203 15173005011 0005754 0 ustar 00 <?php /** * Joomla! Content Management System * * @copyright (C) 2013 Open Source Matters, Inc. <https://www.joomla.org> * @license GNU General Public License version 2 or later; see LICENSE.txt * @note This file has been modified by the Joomla! Project and no longer reflects the original work of its author. */ namespace Joomla\CMS\Encrypt; use Joomla\CMS\Encrypt\AES\AesInterface; use Joomla\CMS\Encrypt\AES\Mcrypt; use Joomla\CMS\Encrypt\AES\OpenSSL; // phpcs:disable PSR1.Files.SideEffects \defined('JPATH_PLATFORM') or die; // phpcs:enable PSR1.Files.SideEffects /** * A simple implementation of AES-128, AES-192 and AES-256 encryption using the * high performance mcrypt library. * * @since 1.0 */ class Aes { /** * The cipher key. * * @var string */ protected $key = ''; /** * The AES encryption adapter in use. * * @var AesInterface */ 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 string $priority Priority which adapter we should try first * * @deprecated 4.3 $strength will be removed in 6.0 */ public function __construct($key, $strength = 128, $mode = 'cbc', $priority = 'openssl') { if ($priority === 'openssl') { $this->adapter = new OpenSSL(); if (!$this->adapter->isSupported()) { $this->adapter = new Mcrypt(); } } else { $this->adapter = new Mcrypt(); if (!$this->adapter->isSupported()) { $this->adapter = new OpenSSL(); } } $this->adapter->setEncryptionMode($mode, $strength); $this->setPassword($key, true); } /** * Sets the password for this instance. * * WARNING: Do not use the legacy mode, it's insecure * * @param string $password The password (either user-provided password or binary encryption key) to use * @param bool $legacyMode True to use the legacy key expansion. We recommend against using it. * * @since 4.0.0 * @return void */ public function setPassword($password, $legacyMode = false) { $this->key = $password; $passLength = \strlen($password); if (\function_exists('mb_strlen')) { $passLength = mb_strlen($password, 'ASCII'); } // Legacy mode was doing something stupid, requiring a key of 32 bytes. DO NOT USE LEGACY MODE! if ($legacyMode && ($passLength != 32)) { // Legacy mode: use the sha256 of the password $this->key = hash('sha256', $password, true); // We have to trim or zero pad the password (we end up throwing half of it away in Rijndael-128 / AES...) $this->key = $this->adapter->resizeKey($this->key, $this->adapter->getBlockSize()); } } /** * Encrypts a string using AES * * @param string $stringToEncrypt The plaintext to encrypt * @param bool $base64encoded Should I Base64-encode the result? * * @return string The cryptotext. Please note that the first 16 bytes of * the raw string is the IV (initialisation vector) which * is necessary for decoding the string. */ public function encryptString($stringToEncrypt, $base64encoded = true) { $blockSize = $this->adapter->getBlockSize(); $randVal = new Randval(); $iv = $randVal->generate($blockSize); $key = $this->getExpandedKey($blockSize, $iv); $cipherText = $this->adapter->encrypt($stringToEncrypt, $key, $iv); // Optionally pass the result through Base64 encoding if ($base64encoded) { $cipherText = base64_encode($cipherText); } // Return the result return $cipherText; } /** * Decrypts a ciphertext into a plaintext string using AES * * @param string $stringToDecrypt The ciphertext to decrypt. The first 16 bytes of the raw string must contain * the IV (initialisation vector). * @param bool $base64encoded Should I Base64-decode the data before decryption? * * @return string The plain text string */ public function decryptString($stringToDecrypt, $base64encoded = true) { if ($base64encoded) { $stringToDecrypt = base64_decode($stringToDecrypt); } // Extract IV $iv_size = $this->adapter->getBlockSize(); $iv = substr($stringToDecrypt, 0, $iv_size); $key = $this->getExpandedKey($iv_size, $iv); // Decrypt the data $plainText = $this->adapter->decrypt($stringToDecrypt, $key); return $plainText; } /** * Is AES encryption supported by this PHP installation? * * @return boolean */ public static function isSupported() { $adapter = new OpenSSL(); if (!$adapter->isSupported()) { $adapter = new Mcrypt(); if (!$adapter->isSupported()) { return false; } } if (!\function_exists('base64_encode')) { return false; } if (!\function_exists('base64_decode')) { return false; } if (!\function_exists('hash_algos')) { return false; } $algorithms = hash_algos(); if (!\in_array('sha256', $algorithms)) { return false; } return true; } /** * Get the expanded key * * @param integer $blockSize Blocksize to process * @param string $iv IV * * @return string */ public function getExpandedKey($blockSize, $iv) { $key = $this->key; $passLength = \strlen($key); if (\function_exists('mb_strlen')) { $passLength = mb_strlen($key, 'ASCII'); } if ($passLength != $blockSize) { $iterations = 1000; $salt = $this->adapter->resizeKey($iv, 16); $key = hash_pbkdf2('sha256', $this->key, $salt, $iterations, $blockSize, true); } return $key; } } if (!\function_exists('hash_pbkdf2')) { /** * Shim for missing hash_pbkdf2 * * @param string $algo Algorithm to use * @param string $password Plaintext password * @param string $salt Salt for the hash * @param integer $count Number of iterations * @param integer $length Length * @param boolean $rawOutput Raw output * * @return string Hashed string */ function hash_pbkdf2($algo, $password, $salt, $count, $length = 0, $rawOutput = false) { if (!\in_array(strtolower($algo), hash_algos())) { trigger_error(__FUNCTION__ . '(): Unknown hashing algorithm: ' . $algo, E_USER_WARNING); } if (!is_numeric($count)) { trigger_error(__FUNCTION__ . '(): expects parameter 4 to be long, ' . \gettype($count) . ' given', E_USER_WARNING); } if (!is_numeric($length)) { trigger_error(__FUNCTION__ . '(): expects parameter 5 to be long, ' . \gettype($length) . ' given', E_USER_WARNING); } if ($count <= 0) { trigger_error(__FUNCTION__ . '(): Iterations must be a positive integer: ' . $count, E_USER_WARNING); } if ($length < 0) { trigger_error(__FUNCTION__ . '(): Length must be greater than or equal to 0: ' . $length, E_USER_WARNING); } $output = ''; $block_count = $length ? ceil($length / \strlen(hash($algo, '', $rawOutput))) : 1; for ($i = 1; $i <= $block_count; $i++) { $last = $xorsum = hash_hmac($algo, $salt . pack('N', $i), $password, true); for ($j = 1; $j < $count; $j++) { $xorsum ^= ($last = hash_hmac($algo, $last, $password, true)); } $output .= $xorsum; } if (!$rawOutput) { $output = bin2hex($output); } return $length ? substr($output, 0, $length) : $output; } } RandValInterface.php 0000644 00000001120 15173005011 0010410 0 ustar 00 <?php /** * Joomla! Content Management System * * @copyright (C) 2017 Open Source Matters, Inc. <https://www.joomla.org> * @license GNU General Public License version 2 or later; see LICENSE.txt */ namespace Joomla\CMS\Encrypt; // phpcs:disable PSR1.Files.SideEffects \defined('JPATH_PLATFORM') or die; // phpcs:enable PSR1.Files.SideEffects /** * Interface RandValInterface * * @since 4.0.0 */ interface RandValInterface { /** * * Returns a cryptographically secure random value. * * @return string * */ public function generate(); }
| ver. 1.4 |
Github
|
.
| PHP 8.3.23 | Generation time: 0 |
proxy
|
phpinfo
|
Settings