[ Index ] |
PHP Cross Reference of Joomla 4.2.2 documentation |
[Summary view] [Print] [Text view]
1 <?php 2 3 /** 4 * Joomla! Content Management System 5 * 6 * @copyright (C) 2013 Open Source Matters, Inc. <https://www.joomla.org> 7 * @license GNU General Public License version 2 or later; see LICENSE.txt 8 * @note This file has been modified by the Joomla! Project and no longer reflects the original work of its author. 9 */ 10 11 namespace Joomla\CMS\Encrypt; 12 13 use Joomla\CMS\Encrypt\AES\AesInterface; 14 use Joomla\CMS\Encrypt\AES\Mcrypt; 15 use Joomla\CMS\Encrypt\AES\OpenSSL; 16 17 // phpcs:disable PSR1.Files.SideEffects 18 \defined('JPATH_PLATFORM') or die; 19 // phpcs:enable PSR1.Files.SideEffects 20 21 /** 22 * A simple implementation of AES-128, AES-192 and AES-256 encryption using the 23 * high performance mcrypt library. 24 * 25 * @since 1.0 26 */ 27 class Aes 28 { 29 /** 30 * The cipher key. 31 * 32 * @var string 33 */ 34 protected $key = ''; 35 36 /** 37 * The AES encryption adapter in use. 38 * 39 * @var AesInterface 40 */ 41 protected $adapter; 42 43 /** 44 * Initialise the AES encryption object. 45 * 46 * Note: If the key is not 16 bytes this class will do a stupid key expansion for legacy reasons (produce the 47 * SHA-256 of the key string and throw away half of it). 48 * 49 * @param string $key The encryption key (password). It can be a raw key (16 bytes) or a passphrase. 50 * @param int $strength Bit strength (128, 192 or 256) – ALWAYS USE 128 BITS. THIS PARAMETER IS DEPRECATED. 51 * @param string $mode Encryption mode. Can be ebc or cbc. We recommend using cbc. 52 * @param string $priority Priority which adapter we should try first 53 * 54 * @deprecated 5.0 $strength will be removed 55 */ 56 public function __construct($key, $strength = 128, $mode = 'cbc', $priority = 'openssl') 57 { 58 if ($priority === 'openssl') { 59 $this->adapter = new OpenSSL(); 60 61 if (!$this->adapter->isSupported()) { 62 $this->adapter = new Mcrypt(); 63 } 64 } else { 65 $this->adapter = new Mcrypt(); 66 67 if (!$this->adapter->isSupported()) { 68 $this->adapter = new OpenSSL(); 69 } 70 } 71 72 $this->adapter->setEncryptionMode($mode, $strength); 73 $this->setPassword($key, true); 74 } 75 76 /** 77 * Sets the password for this instance. 78 * 79 * WARNING: Do not use the legacy mode, it's insecure 80 * 81 * @param string $password The password (either user-provided password or binary encryption key) to use 82 * @param bool $legacyMode True to use the legacy key expansion. We recommend against using it. 83 * 84 * @since 4.0.0 85 * @return void 86 */ 87 public function setPassword($password, $legacyMode = false) 88 { 89 $this->key = $password; 90 91 $passLength = \strlen($password); 92 93 if (\function_exists('mb_strlen')) { 94 $passLength = mb_strlen($password, 'ASCII'); 95 } 96 97 // Legacy mode was doing something stupid, requiring a key of 32 bytes. DO NOT USE LEGACY MODE! 98 if ($legacyMode && ($passLength != 32)) { 99 // Legacy mode: use the sha256 of the password 100 $this->key = hash('sha256', $password, true); 101 102 // We have to trim or zero pad the password (we end up throwing half of it away in Rijndael-128 / AES...) 103 $this->key = $this->adapter->resizeKey($this->key, $this->adapter->getBlockSize()); 104 } 105 } 106 107 /** 108 * Encrypts a string using AES 109 * 110 * @param string $stringToEncrypt The plaintext to encrypt 111 * @param bool $base64encoded Should I Base64-encode the result? 112 * 113 * @return string The cryptotext. Please note that the first 16 bytes of 114 * the raw string is the IV (initialisation vector) which 115 * is necessary for decoding the string. 116 */ 117 public function encryptString($stringToEncrypt, $base64encoded = true) 118 { 119 $blockSize = $this->adapter->getBlockSize(); 120 $randVal = new Randval(); 121 $iv = $randVal->generate($blockSize); 122 123 $key = $this->getExpandedKey($blockSize, $iv); 124 $cipherText = $this->adapter->encrypt($stringToEncrypt, $key, $iv); 125 126 // Optionally pass the result through Base64 encoding 127 if ($base64encoded) { 128 $cipherText = base64_encode($cipherText); 129 } 130 131 // Return the result 132 return $cipherText; 133 } 134 135 /** 136 * Decrypts a ciphertext into a plaintext string using AES 137 * 138 * @param string $stringToDecrypt The ciphertext to decrypt. The first 16 bytes of the raw string must contain 139 * the IV (initialisation vector). 140 * @param bool $base64encoded Should I Base64-decode the data before decryption? 141 * 142 * @return string The plain text string 143 */ 144 public function decryptString($stringToDecrypt, $base64encoded = true) 145 { 146 if ($base64encoded) { 147 $stringToDecrypt = base64_decode($stringToDecrypt); 148 } 149 150 // Extract IV 151 $iv_size = $this->adapter->getBlockSize(); 152 $iv = substr($stringToDecrypt, 0, $iv_size); 153 $key = $this->getExpandedKey($iv_size, $iv); 154 155 // Decrypt the data 156 $plainText = $this->adapter->decrypt($stringToDecrypt, $key); 157 158 return $plainText; 159 } 160 161 /** 162 * Is AES encryption supported by this PHP installation? 163 * 164 * @return boolean 165 */ 166 public static function isSupported() 167 { 168 $adapter = new OpenSSL(); 169 170 if (!$adapter->isSupported()) { 171 $adapter = new Mcrypt(); 172 173 if (!$adapter->isSupported()) { 174 return false; 175 } 176 } 177 178 if (!\function_exists('base64_encode')) { 179 return false; 180 } 181 182 if (!\function_exists('base64_decode')) { 183 return false; 184 } 185 186 if (!\function_exists('hash_algos')) { 187 return false; 188 } 189 190 $algorithms = hash_algos(); 191 192 if (!\in_array('sha256', $algorithms)) { 193 return false; 194 } 195 196 return true; 197 } 198 199 /** 200 * Get the expanded key 201 * 202 * @param integer $blockSize Blocksize to process 203 * @param string $iv IV 204 * 205 * @return string 206 */ 207 public function getExpandedKey($blockSize, $iv) 208 { 209 $key = $this->key; 210 $passLength = \strlen($key); 211 212 if (\function_exists('mb_strlen')) { 213 $passLength = mb_strlen($key, 'ASCII'); 214 } 215 216 if ($passLength != $blockSize) { 217 $iterations = 1000; 218 $salt = $this->adapter->resizeKey($iv, 16); 219 $key = hash_pbkdf2('sha256', $this->key, $salt, $iterations, $blockSize, true); 220 } 221 222 return $key; 223 } 224 } 225 226 if (!\function_exists('hash_pbkdf2')) { 227 /** 228 * Shim for missing hash_pbkdf2 229 * 230 * @param string $algo Algorithm to use 231 * @param string $password Plaintext password 232 * @param string $salt Salt for the hash 233 * @param integer $count Number of iterations 234 * @param integer $length Length 235 * @param boolean $rawOutput Raw output 236 * 237 * @return string Hashed string 238 */ 239 function hash_pbkdf2($algo, $password, $salt, $count, $length = 0, $rawOutput = false) 240 { 241 if (!\in_array(strtolower($algo), hash_algos())) { 242 trigger_error(__FUNCTION__ . '(): Unknown hashing algorithm: ' . $algo, E_USER_WARNING); 243 } 244 245 if (!is_numeric($count)) { 246 trigger_error(__FUNCTION__ . '(): expects parameter 4 to be long, ' . \gettype($count) . ' given', E_USER_WARNING); 247 } 248 249 if (!is_numeric($length)) { 250 trigger_error(__FUNCTION__ . '(): expects parameter 5 to be long, ' . \gettype($length) . ' given', E_USER_WARNING); 251 } 252 253 if ($count <= 0) { 254 trigger_error(__FUNCTION__ . '(): Iterations must be a positive integer: ' . $count, E_USER_WARNING); 255 } 256 257 if ($length < 0) { 258 trigger_error(__FUNCTION__ . '(): Length must be greater than or equal to 0: ' . $length, E_USER_WARNING); 259 } 260 261 $output = ''; 262 $block_count = $length ? ceil($length / \strlen(hash($algo, '', $rawOutput))) : 1; 263 264 for ($i = 1; $i <= $block_count; $i++) { 265 $last = $xorsum = hash_hmac($algo, $salt . pack('N', $i), $password, true); 266 267 for ($j = 1; $j < $count; $j++) { 268 $xorsum ^= ($last = hash_hmac($algo, $last, $password, true)); 269 } 270 271 $output .= $xorsum; 272 } 273 274 if (!$rawOutput) { 275 $output = bin2hex($output); 276 } 277 278 return $length ? substr($output, 0, $length) : $output; 279 } 280 }
title
Description
Body
title
Description
Body
title
Description
Body
title
Body
Generated: Wed Sep 7 05:41:13 2022 | Chilli.vc Blog - For Webmaster,Blog-Writer,System Admin and Domainer |