[ Index ]

PHP Cross Reference of Joomla 4.2.2 documentation

title

Body

[close]

/libraries/src/Encrypt/AES/ -> OpenSSL.php (source)

   1  <?php
   2  
   3  /**
   4   * Joomla! Content Management System
   5   *
   6   * @copyright  (C) 2016 Open Source Matters, Inc. <https://www.joomla.org>
   7   * @license    GNU General Public License version 2 or later; see LICENSE.txt
   8   */
   9  
  10  namespace Joomla\CMS\Encrypt\AES;
  11  
  12  use Joomla\CMS\Encrypt\Randval;
  13  
  14  // phpcs:disable PSR1.Files.SideEffects
  15  \defined('JPATH_PLATFORM') or die;
  16  // phpcs:enable PSR1.Files.SideEffects
  17  
  18  /**
  19   * OpenSSL encryption class
  20   *
  21   * @since   4.0.0
  22   */
  23  class OpenSSL extends AbstractAES implements AesInterface
  24  {
  25      /**
  26       * The OpenSSL options for encryption / decryption
  27       *
  28       * @var  integer
  29       */
  30      protected $openSSLOptions = 0;
  31  
  32      /**
  33       * The encryption method to use
  34       *
  35       * @var  string
  36       */
  37      protected $method = 'aes-128-cbc';
  38  
  39      /**
  40       * Constructor for this class
  41       */
  42      public function __construct()
  43      {
  44          $this->openSSLOptions = OPENSSL_RAW_DATA | OPENSSL_ZERO_PADDING;
  45      }
  46  
  47      /**
  48       * Sets the AES encryption mode.
  49       *
  50       * WARNING: The strength is deprecated as it has a different effect in MCrypt and OpenSSL. MCrypt was abandoned in
  51       * 2003 before the Rijndael-128 algorithm was officially the Advanced Encryption Standard (AES). MCrypt also offered
  52       * Rijndael-192 and Rijndael-256 algorithms with different block sizes. These are NOT used in AES. OpenSSL, however,
  53       * implements AES correctly. It always uses a 128-bit (16 byte) block. The 192 and 256 bit strengths refer to the
  54       * key size, not the block size. Therefore using different strengths in MCrypt and OpenSSL will result in different
  55       * and incompatible ciphertexts.
  56       *
  57       * TL;DR: Always use $strength = 128!
  58       *
  59       * @param   string  $mode      Choose between CBC (recommended) or ECB
  60       * @param   int     $strength  Bit strength of the key (128, 192 or 256 bits). DEPRECATED. READ NOTES ABOVE.
  61       *
  62       * @return  mixed
  63       */
  64      public function setEncryptionMode($mode = 'cbc', $strength = 128)
  65      {
  66          static $availableAlgorithms = null;
  67          static $defaultAlgo = 'aes-128-cbc';
  68  
  69          if (!\is_array($availableAlgorithms)) {
  70              $availableAlgorithms = openssl_get_cipher_methods();
  71  
  72              foreach (
  73                  array('aes-256-cbc', 'aes-256-ecb', 'aes-192-cbc',
  74                  'aes-192-ecb', 'aes-128-cbc', 'aes-128-ecb') as $algo
  75              ) {
  76                  if (\in_array($algo, $availableAlgorithms)) {
  77                      $defaultAlgo = $algo;
  78                      break;
  79                  }
  80              }
  81          }
  82  
  83          $strength = (int) $strength;
  84          $mode     = strtolower($mode);
  85  
  86          if (!\in_array($strength, array(128, 192, 256))) {
  87              $strength = 256;
  88          }
  89  
  90          if (!\in_array($mode, array('cbc', 'ebc'))) {
  91              $mode = 'cbc';
  92          }
  93  
  94          $algo = 'aes-' . $strength . '-' . $mode;
  95  
  96          if (!\in_array($algo, $availableAlgorithms)) {
  97              $algo = $defaultAlgo;
  98          }
  99  
 100          $this->method = $algo;
 101      }
 102  
 103      /**
 104       * Encrypts a string. Returns the raw binary ciphertext.
 105       *
 106       * WARNING: The plaintext is zero-padded to the algorithm's block size. You are advised to store the size of the
 107       * plaintext and trim the string to that length upon decryption.
 108       *
 109       * @param   string       $plainText  The plaintext to encrypt
 110       * @param   string       $key        The raw binary key (will be zero-padded or chopped if its size is different than the block size)
 111       * @param   null|string  $iv         The initialization vector (for CBC mode algorithms)
 112       *
 113       * @return  string  The raw encrypted binary string.
 114       */
 115      public function encrypt($plainText, $key, $iv = null)
 116      {
 117          $iv_size = $this->getBlockSize();
 118          $key     = $this->resizeKey($key, $iv_size);
 119          $iv      = $this->resizeKey($iv, $iv_size);
 120  
 121          if (empty($iv)) {
 122              $randVal   = new Randval();
 123              $iv        = $randVal->generate($iv_size);
 124          }
 125  
 126          $plainText .= $this->getZeroPadding($plainText, $iv_size);
 127          $cipherText = openssl_encrypt($plainText, $this->method, $key, $this->openSSLOptions, $iv);
 128          $cipherText = $iv . $cipherText;
 129  
 130          return $cipherText;
 131      }
 132  
 133      /**
 134       * Decrypts a string. Returns the raw binary plaintext.
 135       *
 136       * $ciphertext MUST start with the IV followed by the ciphertext, even for EBC data (the first block of data is
 137       * dropped in EBC mode since there is no concept of IV in EBC).
 138       *
 139       * WARNING: The returned plaintext is zero-padded to the algorithm's block size during encryption. You are advised
 140       * to trim the string to the original plaintext's length upon decryption. While rtrim($decrypted, "\0") sounds
 141       * appealing it's NOT the correct approach for binary data (zero bytes may actually be part of your plaintext, not
 142       * just padding!).
 143       *
 144       * @param   string  $cipherText  The ciphertext to encrypt
 145       * @param   string  $key         The raw binary key (will be zero-padded or chopped if its size is different than the block size)
 146       *
 147       * @return  string  The raw unencrypted binary string.
 148       */
 149      public function decrypt($cipherText, $key)
 150      {
 151          $iv_size    = $this->getBlockSize();
 152          $key        = $this->resizeKey($key, $iv_size);
 153          $iv         = substr($cipherText, 0, $iv_size);
 154          $cipherText = substr($cipherText, $iv_size);
 155          $plainText  = openssl_decrypt($cipherText, $this->method, $key, $this->openSSLOptions, $iv);
 156  
 157          // Remove the zero padding
 158          return rtrim($plainText, "\0");
 159      }
 160  
 161      /**
 162       * Is this adapter supported?
 163       *
 164       * @return  boolean
 165       */
 166      public function isSupported()
 167      {
 168          if (!\function_exists('openssl_get_cipher_methods')) {
 169              return false;
 170          }
 171  
 172          if (!\function_exists('openssl_random_pseudo_bytes')) {
 173              return false;
 174          }
 175  
 176          if (!\function_exists('openssl_cipher_iv_length')) {
 177              return false;
 178          }
 179  
 180          if (!\function_exists('openssl_encrypt')) {
 181              return false;
 182          }
 183  
 184          if (!\function_exists('openssl_decrypt')) {
 185              return false;
 186          }
 187  
 188          if (!\function_exists('hash')) {
 189              return false;
 190          }
 191  
 192          if (!\function_exists('hash_algos')) {
 193              return false;
 194          }
 195  
 196          $algorithms = openssl_get_cipher_methods();
 197  
 198          if (!\in_array('aes-128-cbc', $algorithms)) {
 199              return false;
 200          }
 201  
 202          $algorithms = hash_algos();
 203  
 204          if (!\in_array('sha256', $algorithms)) {
 205              return false;
 206          }
 207  
 208          return true;
 209      }
 210  
 211      /**
 212       * Returns the encryption block size in bytes
 213       *
 214       * @return  integer
 215       */
 216      public function getBlockSize()
 217      {
 218          return openssl_cipher_iv_length($this->method);
 219      }
 220  }


Generated: Wed Sep 7 05:41:13 2022 Chilli.vc Blog - For Webmaster,Blog-Writer,System Admin and Domainer