[ Index ]

PHP Cross Reference of Joomla 4.2.2 documentation

title

Body

[close]

/libraries/vendor/defuse/php-encryption/src/ -> KeyOrPassword.php (source)

   1  <?php
   2  
   3  namespace Defuse\Crypto;
   4  
   5  use Defuse\Crypto\Exception as Ex;
   6  
   7  final class KeyOrPassword
   8  {
   9      const PBKDF2_ITERATIONS    = 100000;
  10      const SECRET_TYPE_KEY      = 1;
  11      const SECRET_TYPE_PASSWORD = 2;
  12  
  13      /**
  14       * @var int
  15       */
  16      private $secret_type = 0;
  17  
  18      /**
  19       * @var Key|string
  20       */
  21      private $secret;
  22  
  23      /**
  24       * Initializes an instance of KeyOrPassword from a key.
  25       *
  26       * @param Key $key
  27       *
  28       * @return KeyOrPassword
  29       */
  30      public static function createFromKey(Key $key)
  31      {
  32          return new KeyOrPassword(self::SECRET_TYPE_KEY, $key);
  33      }
  34  
  35      /**
  36       * Initializes an instance of KeyOrPassword from a password.
  37       *
  38       * @param string $password
  39       *
  40       * @return KeyOrPassword
  41       */
  42      public static function createFromPassword($password)
  43      {
  44          return new KeyOrPassword(self::SECRET_TYPE_PASSWORD, $password);
  45      }
  46  
  47      /**
  48       * Derives authentication and encryption keys from the secret, using a slow
  49       * key derivation function if the secret is a password.
  50       *
  51       * @param string $salt
  52       *
  53       * @throws Ex\CryptoException
  54       * @throws Ex\EnvironmentIsBrokenException
  55       *
  56       * @return DerivedKeys
  57       */
  58      public function deriveKeys($salt)
  59      {
  60          Core::ensureTrue(
  61              Core::ourStrlen($salt) === Core::SALT_BYTE_SIZE,
  62              'Bad salt.'
  63          );
  64  
  65          if ($this->secret_type === self::SECRET_TYPE_KEY) {
  66              Core::ensureTrue($this->secret instanceof Key);
  67              /**
  68               * @psalm-suppress PossiblyInvalidMethodCall
  69               */
  70              $akey = Core::HKDF(
  71                  Core::HASH_FUNCTION_NAME,
  72                  $this->secret->getRawBytes(),
  73                  Core::KEY_BYTE_SIZE,
  74                  Core::AUTHENTICATION_INFO_STRING,
  75                  $salt
  76              );
  77              /**
  78               * @psalm-suppress PossiblyInvalidMethodCall
  79               */
  80              $ekey = Core::HKDF(
  81                  Core::HASH_FUNCTION_NAME,
  82                  $this->secret->getRawBytes(),
  83                  Core::KEY_BYTE_SIZE,
  84                  Core::ENCRYPTION_INFO_STRING,
  85                  $salt
  86              );
  87              return new DerivedKeys($akey, $ekey);
  88          } elseif ($this->secret_type === self::SECRET_TYPE_PASSWORD) {
  89              Core::ensureTrue(\is_string($this->secret));
  90              /* Our PBKDF2 polyfill is vulnerable to a DoS attack documented in
  91               * GitHub issue #230. The fix is to pre-hash the password to ensure
  92               * it is short. We do the prehashing here instead of in pbkdf2() so
  93               * that pbkdf2() still computes the function as defined by the
  94               * standard. */
  95  
  96              /**
  97               * @psalm-suppress PossiblyInvalidArgument
  98               */
  99              $prehash = \hash(Core::HASH_FUNCTION_NAME, $this->secret, true);
 100  
 101              $prekey = Core::pbkdf2(
 102                  Core::HASH_FUNCTION_NAME,
 103                  $prehash,
 104                  $salt,
 105                  self::PBKDF2_ITERATIONS,
 106                  Core::KEY_BYTE_SIZE,
 107                  true
 108              );
 109              $akey = Core::HKDF(
 110                  Core::HASH_FUNCTION_NAME,
 111                  $prekey,
 112                  Core::KEY_BYTE_SIZE,
 113                  Core::AUTHENTICATION_INFO_STRING,
 114                  $salt
 115              );
 116              /* Note the cryptographic re-use of $salt here. */
 117              $ekey = Core::HKDF(
 118                  Core::HASH_FUNCTION_NAME,
 119                  $prekey,
 120                  Core::KEY_BYTE_SIZE,
 121                  Core::ENCRYPTION_INFO_STRING,
 122                  $salt
 123              );
 124              return new DerivedKeys($akey, $ekey);
 125          } else {
 126              throw new Ex\EnvironmentIsBrokenException('Bad secret type.');
 127          }
 128      }
 129  
 130      /**
 131       * Constructor for KeyOrPassword.
 132       *
 133       * @param int   $secret_type
 134       * @param mixed $secret      (either a Key or a password string)
 135       */
 136      private function __construct($secret_type, $secret)
 137      {
 138          // The constructor is private, so these should never throw.
 139          if ($secret_type === self::SECRET_TYPE_KEY) {
 140              Core::ensureTrue($secret instanceof Key);
 141          } elseif ($secret_type === self::SECRET_TYPE_PASSWORD) {
 142              Core::ensureTrue(\is_string($secret));
 143          } else {
 144              throw new Ex\EnvironmentIsBrokenException('Bad secret type.');
 145          }
 146          $this->secret_type = $secret_type;
 147          $this->secret = $secret;
 148      }
 149  }


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