[ Index ]

PHP Cross Reference of Joomla 4.2.2 documentation

title

Body

[close]

/libraries/vendor/phpseclib/phpseclib/phpseclib/Crypt/ -> RSA.php (source)

   1  <?php
   2  
   3  /**
   4   * Pure-PHP PKCS#1 (v2.1) compliant implementation of RSA.
   5   *
   6   * PHP version 5
   7   *
   8   * Here's an example of how to encrypt and decrypt text with this library:
   9   * <code>
  10   * <?php
  11   * include 'vendor/autoload.php';
  12   *
  13   * $private = \phpseclib3\Crypt\RSA::createKey();
  14   * $public = $private->getPublicKey();
  15   *
  16   * $plaintext = 'terrafrost';
  17   *
  18   * $ciphertext = $public->encrypt($plaintext);
  19   *
  20   * echo $private->decrypt($ciphertext);
  21   * ?>
  22   * </code>
  23   *
  24   * Here's an example of how to create signatures and verify signatures with this library:
  25   * <code>
  26   * <?php
  27   * include 'vendor/autoload.php';
  28   *
  29   * $private = \phpseclib3\Crypt\RSA::createKey();
  30   * $public = $private->getPublicKey();
  31   *
  32   * $plaintext = 'terrafrost';
  33   *
  34   * $signature = $private->sign($plaintext);
  35   *
  36   * echo $public->verify($plaintext, $signature) ? 'verified' : 'unverified';
  37   * ?>
  38   * </code>
  39   *
  40   * One thing to consider when using this: so phpseclib uses PSS mode by default.
  41   * Technically, id-RSASSA-PSS has a different key format than rsaEncryption. So
  42   * should phpseclib save to the id-RSASSA-PSS format by default or the
  43   * rsaEncryption format? For stand-alone keys I figure rsaEncryption is better
  44   * because SSH doesn't use PSS and idk how many SSH servers would be able to
  45   * decode an id-RSASSA-PSS key. For X.509 certificates the id-RSASSA-PSS
  46   * format is used by default (unless you change it up to use PKCS1 instead)
  47   *
  48   * @category  Crypt
  49   * @package   RSA
  50   * @author    Jim Wigginton <[email protected]>
  51   * @copyright 2009 Jim Wigginton
  52   * @license   http://www.opensource.org/licenses/mit-license.html  MIT License
  53   * @link      http://phpseclib.sourceforge.net
  54   */
  55  
  56  namespace phpseclib3\Crypt;
  57  
  58  use phpseclib3\Crypt\Common\AsymmetricKey;
  59  use phpseclib3\Crypt\RSA\Formats\Keys\PSS;
  60  use phpseclib3\Crypt\RSA\PrivateKey;
  61  use phpseclib3\Crypt\RSA\PublicKey;
  62  use phpseclib3\Exception\InconsistentSetupException;
  63  use phpseclib3\Exception\UnsupportedAlgorithmException;
  64  use phpseclib3\Math\BigInteger;
  65  
  66  /**
  67   * Pure-PHP PKCS#1 compliant implementation of RSA.
  68   *
  69   * @package RSA
  70   * @author  Jim Wigginton <[email protected]>
  71   * @access  public
  72   */
  73  abstract class RSA extends AsymmetricKey
  74  {
  75      /**
  76       * Algorithm Name
  77       *
  78       * @var string
  79       * @access private
  80       */
  81      const ALGORITHM = 'RSA';
  82  
  83      /**
  84       * Use {@link http://en.wikipedia.org/wiki/Optimal_Asymmetric_Encryption_Padding Optimal Asymmetric Encryption Padding}
  85       * (OAEP) for encryption / decryption.
  86       *
  87       * Uses sha256 by default
  88       *
  89       * @see self::setHash()
  90       * @see self::setMGFHash()
  91       * @access public
  92       * @see self::encrypt()
  93       * @see self::decrypt()
  94       */
  95      const ENCRYPTION_OAEP = 1;
  96  
  97      /**
  98       * Use PKCS#1 padding.
  99       *
 100       * Although self::PADDING_OAEP / self::PADDING_PSS  offers more security, including PKCS#1 padding is necessary for purposes of backwards
 101       * compatibility with protocols (like SSH-1) written before OAEP's introduction.
 102       *
 103       * @access public
 104       * @see self::encrypt()
 105       * @see self::decrypt()
 106       */
 107      const ENCRYPTION_PKCS1 = 2;
 108  
 109      /**
 110       * Do not use any padding
 111       *
 112       * Although this method is not recommended it can none-the-less sometimes be useful if you're trying to decrypt some legacy
 113       * stuff, if you're trying to diagnose why an encrypted message isn't decrypting, etc.
 114       *
 115       * @access public
 116       * @see self::encrypt()
 117       * @see self::decrypt()
 118       */
 119      const ENCRYPTION_NONE = 4;
 120  
 121      /**
 122       * Use the Probabilistic Signature Scheme for signing
 123       *
 124       * Uses sha256 and 0 as the salt length
 125       *
 126       * @see self::setSaltLength()
 127       * @see self::setMGFHash()
 128       * @see self::setHash()
 129       * @see self::sign()
 130       * @see self::verify()
 131       * @see self::setHash()
 132       * @access public
 133       */
 134      const SIGNATURE_PSS = 16;
 135  
 136      /**
 137       * Use a relaxed version of PKCS#1 padding for signature verification
 138       *
 139       * @see self::sign()
 140       * @see self::verify()
 141       * @see self::setHash()
 142       * @access public
 143       */
 144      const SIGNATURE_RELAXED_PKCS1 = 32;
 145  
 146      /**
 147       * Use PKCS#1 padding for signature verification
 148       *
 149       * @see self::sign()
 150       * @see self::verify()
 151       * @see self::setHash()
 152       * @access public
 153       */
 154      const SIGNATURE_PKCS1 = 64;
 155  
 156      /**
 157       * Encryption padding mode
 158       *
 159       * @var int
 160       * @access private
 161       */
 162      protected $encryptionPadding = self::ENCRYPTION_OAEP;
 163  
 164      /**
 165       * Signature padding mode
 166       *
 167       * @var int
 168       * @access private
 169       */
 170      protected $signaturePadding = self::SIGNATURE_PSS;
 171  
 172      /**
 173       * Length of hash function output
 174       *
 175       * @var int
 176       * @access private
 177       */
 178      protected $hLen;
 179  
 180      /**
 181       * Length of salt
 182       *
 183       * @var int
 184       * @access private
 185       */
 186      protected $sLen;
 187  
 188      /**
 189       * Label
 190       *
 191       * @var string
 192       * @access private
 193       */
 194      protected $label = '';
 195  
 196      /**
 197       * Hash function for the Mask Generation Function
 198       *
 199       * @var \phpseclib3\Crypt\Hash
 200       * @access private
 201       */
 202      protected $mgfHash;
 203  
 204      /**
 205       * Length of MGF hash function output
 206       *
 207       * @var int
 208       * @access private
 209       */
 210      protected $mgfHLen;
 211  
 212      /**
 213       * Modulus (ie. n)
 214       *
 215       * @var \phpseclib3\Math\BigInteger
 216       * @access private
 217       */
 218      protected $modulus;
 219  
 220      /**
 221       * Modulus length
 222       *
 223       * @var \phpseclib3\Math\BigInteger
 224       * @access private
 225       */
 226      protected $k;
 227  
 228      /**
 229       * Exponent (ie. e or d)
 230       *
 231       * @var \phpseclib3\Math\BigInteger
 232       * @access private
 233       */
 234      protected $exponent;
 235  
 236      /**
 237       * Default public exponent
 238       *
 239       * @var int
 240       * @link http://en.wikipedia.org/wiki/65537_%28number%29
 241       * @access private
 242       */
 243      private static $defaultExponent = 65537;
 244  
 245      /**
 246       * Enable Blinding?
 247       *
 248       * @var bool
 249       * @access private
 250       */
 251      protected static $enableBlinding = true;
 252  
 253      /**
 254       * OpenSSL configuration file name.
 255       *
 256       * @see self::createKey()
 257       * @var ?string
 258       */
 259      protected static $configFile;
 260  
 261      /**
 262       * Smallest Prime
 263       *
 264       * Per <http://cseweb.ucsd.edu/~hovav/dist/survey.pdf#page=5>, this number ought not result in primes smaller
 265       * than 256 bits. As a consequence if the key you're trying to create is 1024 bits and you've set smallestPrime
 266       * to 384 bits then you're going to get a 384 bit prime and a 640 bit prime (384 + 1024 % 384). At least if
 267       * engine is set to self::ENGINE_INTERNAL. If Engine is set to self::ENGINE_OPENSSL then smallest Prime is
 268       * ignored (ie. multi-prime RSA support is more intended as a way to speed up RSA key generation when there's
 269       * a chance neither gmp nor OpenSSL are installed)
 270       *
 271       * @var int
 272       * @access private
 273       */
 274      private static $smallestPrime = 4096;
 275  
 276      /**
 277       * Sets the public exponent for key generation
 278       *
 279       * This will be 65537 unless changed.
 280       *
 281       * @access public
 282       * @param int $val
 283       */
 284      public static function setExponent($val)
 285      {
 286          self::$defaultExponent = $val;
 287      }
 288  
 289      /**
 290       * Sets the smallest prime number in bits. Used for key generation
 291       *
 292       * This will be 4096 unless changed.
 293       *
 294       * @access public
 295       * @param int $val
 296       */
 297      public static function setSmallestPrime($val)
 298      {
 299          self::$smallestPrime = $val;
 300      }
 301  
 302      /**
 303       * Sets the OpenSSL config file path
 304       *
 305       * Set to the empty string to use the default config file
 306       *
 307       * @access public
 308       * @param string $val
 309       */
 310      public static function setOpenSSLConfigPath($val)
 311      {
 312          self::$configFile = $val;
 313      }
 314  
 315      /**
 316       * Create a private key
 317       *
 318       * The public key can be extracted from the private key
 319       *
 320       * @return RSA
 321       * @access public
 322       * @param int $bits
 323       */
 324      public static function createKey($bits = 2048)
 325      {
 326          self::initialize_static_variables();
 327  
 328          $regSize = $bits >> 1; // divide by two to see how many bits P and Q would be
 329          if ($regSize > self::$smallestPrime) {
 330              $num_primes = floor($bits / self::$smallestPrime);
 331              $regSize = self::$smallestPrime;
 332          } else {
 333              $num_primes = 2;
 334          }
 335  
 336          if ($num_primes == 2 && $bits >= 384 && self::$defaultExponent == 65537) {
 337              if (!isset(self::$engines['PHP'])) {
 338                  self::useBestEngine();
 339              }
 340  
 341              // OpenSSL uses 65537 as the exponent and requires RSA keys be 384 bits minimum
 342              if (self::$engines['OpenSSL']) {
 343                  $config = [];
 344                  if (self::$configFile) {
 345                      $config['config'] = self::$configFile;
 346                  }
 347                  $rsa = openssl_pkey_new(['private_key_bits' => $bits] + $config);
 348                  openssl_pkey_export($rsa, $privatekeystr, null, $config);
 349  
 350                  // clear the buffer of error strings stemming from a minimalistic openssl.cnf
 351                  while (openssl_error_string() !== false) {
 352                  }
 353  
 354                  return RSA::load($privatekeystr);
 355              }
 356          }
 357  
 358          static $e;
 359          if (!isset($e)) {
 360              $e = new BigInteger(self::$defaultExponent);
 361          }
 362  
 363          $n = clone self::$one;
 364          $exponents = $coefficients = $primes = [];
 365          $lcm = [
 366              'top' => clone self::$one,
 367              'bottom' => false
 368          ];
 369  
 370          do {
 371              for ($i = 1; $i <= $num_primes; $i++) {
 372                  if ($i != $num_primes) {
 373                      $primes[$i] = BigInteger::randomPrime($regSize);
 374                  } else {
 375                      extract(BigInteger::minMaxBits($bits));
 376                      /** @var BigInteger $min
 377                       *  @var BigInteger $max
 378                       */
 379                      list($min) = $min->divide($n);
 380                      $min = $min->add(self::$one);
 381                      list($max) = $max->divide($n);
 382                      $primes[$i] = BigInteger::randomRangePrime($min, $max);
 383                  }
 384  
 385                  // the first coefficient is calculated differently from the rest
 386                  // ie. instead of being $primes[1]->modInverse($primes[2]), it's $primes[2]->modInverse($primes[1])
 387                  if ($i > 2) {
 388                      $coefficients[$i] = $n->modInverse($primes[$i]);
 389                  }
 390  
 391                  $n = $n->multiply($primes[$i]);
 392  
 393                  $temp = $primes[$i]->subtract(self::$one);
 394  
 395                  // textbook RSA implementations use Euler's totient function instead of the least common multiple.
 396                  // see http://en.wikipedia.org/wiki/Euler%27s_totient_function
 397                  $lcm['top'] = $lcm['top']->multiply($temp);
 398                  $lcm['bottom'] = $lcm['bottom'] === false ? $temp : $lcm['bottom']->gcd($temp);
 399              }
 400  
 401              list($temp) = $lcm['top']->divide($lcm['bottom']);
 402              $gcd = $temp->gcd($e);
 403              $i0 = 1;
 404          } while (!$gcd->equals(self::$one));
 405  
 406          $coefficients[2] = $primes[2]->modInverse($primes[1]);
 407  
 408          $d = $e->modInverse($temp);
 409  
 410          foreach ($primes as $i => $prime) {
 411              $temp = $prime->subtract(self::$one);
 412              $exponents[$i] = $e->modInverse($temp);
 413          }
 414  
 415          // from <http://tools.ietf.org/html/rfc3447#appendix-A.1.2>:
 416          // RSAPrivateKey ::= SEQUENCE {
 417          //     version           Version,
 418          //     modulus           INTEGER,  -- n
 419          //     publicExponent    INTEGER,  -- e
 420          //     privateExponent   INTEGER,  -- d
 421          //     prime1            INTEGER,  -- p
 422          //     prime2            INTEGER,  -- q
 423          //     exponent1         INTEGER,  -- d mod (p-1)
 424          //     exponent2         INTEGER,  -- d mod (q-1)
 425          //     coefficient       INTEGER,  -- (inverse of q) mod p
 426          //     otherPrimeInfos   OtherPrimeInfos OPTIONAL
 427          // }
 428          $privatekey = new PrivateKey();
 429          $privatekey->modulus = $n;
 430          $privatekey->k = $bits >> 3;
 431          $privatekey->publicExponent = $e;
 432          $privatekey->exponent = $d;
 433          $privatekey->primes = $primes;
 434          $privatekey->exponents = $exponents;
 435          $privatekey->coefficients = $coefficients;
 436  
 437          /*
 438          $publickey = new PublicKey;
 439          $publickey->modulus = $n;
 440          $publickey->k = $bits >> 3;
 441          $publickey->exponent = $e;
 442          $publickey->publicExponent = $e;
 443          $publickey->isPublic = true;
 444          */
 445  
 446          return $privatekey;
 447      }
 448  
 449      /**
 450       * OnLoad Handler
 451       *
 452       * @return bool
 453       * @access protected
 454       * @param array $components
 455       */
 456      protected static function onLoad($components)
 457      {
 458          $key = $components['isPublicKey'] ?
 459              new PublicKey() :
 460              new PrivateKey();
 461  
 462          $key->modulus = $components['modulus'];
 463          $key->publicExponent = $components['publicExponent'];
 464          $key->k = $key->modulus->getLengthInBytes();
 465  
 466          if ($components['isPublicKey'] || !isset($components['privateExponent'])) {
 467              $key->exponent = $key->publicExponent;
 468          } else {
 469              $key->privateExponent = $components['privateExponent'];
 470              $key->exponent = $key->privateExponent;
 471              $key->primes = $components['primes'];
 472              $key->exponents = $components['exponents'];
 473              $key->coefficients = $components['coefficients'];
 474          }
 475  
 476          if ($components['format'] == PSS::class) {
 477              // in the X509 world RSA keys are assumed to use PKCS1 padding by default. only if the key is
 478              // explicitly a PSS key is the use of PSS assumed. phpseclib does not work like this. phpseclib
 479              // uses PSS padding by default. it assumes the more secure method by default and altho it provides
 480              // for the less secure PKCS1 method you have to go out of your way to use it. this is consistent
 481              // with the latest trends in crypto. libsodium (NaCl) is actually a little more extreme in that
 482              // not only does it defaults to the most secure methods - it doesn't even let you choose less
 483              // secure methods
 484              //$key = $key->withPadding(self::SIGNATURE_PSS);
 485              if (isset($components['hash'])) {
 486                  $key = $key->withHash($components['hash']);
 487              }
 488              if (isset($components['MGFHash'])) {
 489                  $key = $key->withMGFHash($components['MGFHash']);
 490              }
 491              if (isset($components['saltLength'])) {
 492                  $key = $key->withSaltLength($components['saltLength']);
 493              }
 494          }
 495  
 496          return $key;
 497      }
 498  
 499      /**
 500       * Initialize static variables
 501       */
 502      protected static function initialize_static_variables()
 503      {
 504          if (!isset(self::$configFile)) {
 505              self::$configFile = dirname(__FILE__) . '/../openssl.cnf';
 506          }
 507  
 508          parent::initialize_static_variables();
 509      }
 510  
 511      /**
 512       * Constructor
 513       *
 514       * PublicKey and PrivateKey objects can only be created from abstract RSA class
 515       */
 516      protected function __construct()
 517      {
 518          parent::__construct();
 519  
 520          $this->hLen = $this->hash->getLengthInBytes();
 521          $this->mgfHash = new Hash('sha256');
 522          $this->mgfHLen = $this->mgfHash->getLengthInBytes();
 523      }
 524  
 525      /**
 526       * Integer-to-Octet-String primitive
 527       *
 528       * See {@link http://tools.ietf.org/html/rfc3447#section-4.1 RFC3447#section-4.1}.
 529       *
 530       * @access private
 531       * @param bool|\phpseclib3\Math\BigInteger $x
 532       * @param int $xLen
 533       * @return bool|string
 534       */
 535      protected function i2osp($x, $xLen)
 536      {
 537          if ($x === false) {
 538              return false;
 539          }
 540          $x = $x->toBytes();
 541          if (strlen($x) > $xLen) {
 542              throw new \OutOfRangeException('Resultant string length out of range');
 543          }
 544          return str_pad($x, $xLen, chr(0), STR_PAD_LEFT);
 545      }
 546  
 547      /**
 548       * Octet-String-to-Integer primitive
 549       *
 550       * See {@link http://tools.ietf.org/html/rfc3447#section-4.2 RFC3447#section-4.2}.
 551       *
 552       * @access private
 553       * @param string $x
 554       * @return \phpseclib3\Math\BigInteger
 555       */
 556      protected function os2ip($x)
 557      {
 558          return new BigInteger($x, 256);
 559      }
 560  
 561      /**
 562       * EMSA-PKCS1-V1_5-ENCODE
 563       *
 564       * See {@link http://tools.ietf.org/html/rfc3447#section-9.2 RFC3447#section-9.2}.
 565       *
 566       * @access private
 567       * @param string $m
 568       * @param int $emLen
 569       * @throws \LengthException if the intended encoded message length is too short
 570       * @return string
 571       */
 572      protected function emsa_pkcs1_v1_5_encode($m, $emLen)
 573      {
 574          $h = $this->hash->hash($m);
 575  
 576          // see http://tools.ietf.org/html/rfc3447#page-43
 577          switch ($this->hash->getHash()) {
 578              case 'md2':
 579                  $t = "\x30\x20\x30\x0c\x06\x08\x2a\x86\x48\x86\xf7\x0d\x02\x02\x05\x00\x04\x10";
 580                  break;
 581              case 'md5':
 582                  $t = "\x30\x20\x30\x0c\x06\x08\x2a\x86\x48\x86\xf7\x0d\x02\x05\x05\x00\x04\x10";
 583                  break;
 584              case 'sha1':
 585                  $t = "\x30\x21\x30\x09\x06\x05\x2b\x0e\x03\x02\x1a\x05\x00\x04\x14";
 586                  break;
 587              case 'sha256':
 588                  $t = "\x30\x31\x30\x0d\x06\x09\x60\x86\x48\x01\x65\x03\x04\x02\x01\x05\x00\x04\x20";
 589                  break;
 590              case 'sha384':
 591                  $t = "\x30\x41\x30\x0d\x06\x09\x60\x86\x48\x01\x65\x03\x04\x02\x02\x05\x00\x04\x30";
 592                  break;
 593              case 'sha512':
 594                  $t = "\x30\x51\x30\x0d\x06\x09\x60\x86\x48\x01\x65\x03\x04\x02\x03\x05\x00\x04\x40";
 595                  break;
 596              // from https://www.emc.com/collateral/white-papers/h11300-pkcs-1v2-2-rsa-cryptography-standard-wp.pdf#page=40
 597              case 'sha224':
 598                  $t = "\x30\x2d\x30\x0d\x06\x09\x60\x86\x48\x01\x65\x03\x04\x02\x04\x05\x00\x04\x1c";
 599                  break;
 600              case 'sha512/224':
 601                  $t = "\x30\x2d\x30\x0d\x06\x09\x60\x86\x48\x01\x65\x03\x04\x02\x05\x05\x00\x04\x1c";
 602                  break;
 603              case 'sha512/256':
 604                  $t = "\x30\x31\x30\x0d\x06\x09\x60\x86\x48\x01\x65\x03\x04\x02\x06\x05\x00\x04\x20";
 605          }
 606          $t .= $h;
 607          $tLen = strlen($t);
 608  
 609          if ($emLen < $tLen + 11) {
 610              throw new \LengthException('Intended encoded message length too short');
 611          }
 612  
 613          $ps = str_repeat(chr(0xFF), $emLen - $tLen - 3);
 614  
 615          $em = "\0\1$ps\0$t";
 616  
 617          return $em;
 618      }
 619  
 620      /**
 621       * EMSA-PKCS1-V1_5-ENCODE (without NULL)
 622       *
 623       * Quoting https://tools.ietf.org/html/rfc8017#page-65,
 624       *
 625       * "The parameters field associated with id-sha1, id-sha224, id-sha256,
 626       *  id-sha384, id-sha512, id-sha512/224, and id-sha512/256 should
 627       *  generally be omitted, but if present, it shall have a value of type
 628       *  NULL"
 629       *
 630       * @access private
 631       * @param string $m
 632       * @param int $emLen
 633       * @return string
 634       */
 635      protected function emsa_pkcs1_v1_5_encode_without_null($m, $emLen)
 636      {
 637          $h = $this->hash->hash($m);
 638  
 639          // see http://tools.ietf.org/html/rfc3447#page-43
 640          switch ($this->hash->getHash()) {
 641              case 'sha1':
 642                  $t = "\x30\x1f\x30\x07\x06\x05\x2b\x0e\x03\x02\x1a\x04\x14";
 643                  break;
 644              case 'sha256':
 645                  $t = "\x30\x2f\x30\x0b\x06\x09\x60\x86\x48\x01\x65\x03\x04\x02\x01\x04\x20";
 646                  break;
 647              case 'sha384':
 648                  $t = "\x30\x3f\x30\x0b\x06\x09\x60\x86\x48\x01\x65\x03\x04\x02\x02\x04\x30";
 649                  break;
 650              case 'sha512':
 651                  $t = "\x30\x4f\x30\x0b\x06\x09\x60\x86\x48\x01\x65\x03\x04\x02\x03\x04\x40";
 652                  break;
 653              // from https://www.emc.com/collateral/white-papers/h11300-pkcs-1v2-2-rsa-cryptography-standard-wp.pdf#page=40
 654              case 'sha224':
 655                  $t = "\x30\x2b\x30\x0b\x06\x09\x60\x86\x48\x01\x65\x03\x04\x02\x04\x04\x1c";
 656                  break;
 657              case 'sha512/224':
 658                  $t = "\x30\x2b\x30\x0b\x06\x09\x60\x86\x48\x01\x65\x03\x04\x02\x05\x04\x1c";
 659                  break;
 660              case 'sha512/256':
 661                  $t = "\x30\x2f\x30\x0b\x06\x09\x60\x86\x48\x01\x65\x03\x04\x02\x06\x04\x20";
 662                  break;
 663              default:
 664                  throw new UnsupportedAlgorithmException('md2 and md5 require NULLs');
 665          }
 666          $t .= $h;
 667          $tLen = strlen($t);
 668  
 669          if ($emLen < $tLen + 11) {
 670              throw new \LengthException('Intended encoded message length too short');
 671          }
 672  
 673          $ps = str_repeat(chr(0xFF), $emLen - $tLen - 3);
 674  
 675          $em = "\0\1$ps\0$t";
 676  
 677          return $em;
 678      }
 679  
 680      /**
 681       * MGF1
 682       *
 683       * See {@link http://tools.ietf.org/html/rfc3447#appendix-B.2.1 RFC3447#appendix-B.2.1}.
 684       *
 685       * @access private
 686       * @param string $mgfSeed
 687       * @param int $maskLen
 688       * @return string
 689       */
 690      protected function mgf1($mgfSeed, $maskLen)
 691      {
 692          // if $maskLen would yield strings larger than 4GB, PKCS#1 suggests a "Mask too long" error be output.
 693  
 694          $t = '';
 695          $count = ceil($maskLen / $this->mgfHLen);
 696          for ($i = 0; $i < $count; $i++) {
 697              $c = pack('N', $i);
 698              $t .= $this->mgfHash->hash($mgfSeed . $c);
 699          }
 700  
 701          return substr($t, 0, $maskLen);
 702      }
 703  
 704      /**
 705       * Returns the key size
 706       *
 707       * More specifically, this returns the size of the modulo in bits.
 708       *
 709       * @access public
 710       * @return int
 711       */
 712      public function getLength()
 713      {
 714          return !isset($this->modulus) ? 0 : $this->modulus->getLength();
 715      }
 716  
 717      /**
 718       * Determines which hashing function should be used
 719       *
 720       * Used with signature production / verification and (if the encryption mode is self::PADDING_OAEP) encryption and
 721       * decryption.
 722       *
 723       * @access public
 724       * @param string $hash
 725       */
 726      public function withHash($hash)
 727      {
 728          $new = clone $this;
 729  
 730          // \phpseclib3\Crypt\Hash supports algorithms that PKCS#1 doesn't support.  md5-96 and sha1-96, for example.
 731          switch (strtolower($hash)) {
 732              case 'md2':
 733              case 'md5':
 734              case 'sha1':
 735              case 'sha256':
 736              case 'sha384':
 737              case 'sha512':
 738              case 'sha224':
 739              case 'sha512/224':
 740              case 'sha512/256':
 741                  $new->hash = new Hash($hash);
 742                  break;
 743              default:
 744                  throw new UnsupportedAlgorithmException(
 745                      'The only supported hash algorithms are: md2, md5, sha1, sha256, sha384, sha512, sha224, sha512/224, sha512/256'
 746                  );
 747          }
 748          $new->hLen = $new->hash->getLengthInBytes();
 749  
 750          return $new;
 751      }
 752  
 753      /**
 754       * Determines which hashing function should be used for the mask generation function
 755       *
 756       * The mask generation function is used by self::PADDING_OAEP and self::PADDING_PSS and although it's
 757       * best if Hash and MGFHash are set to the same thing this is not a requirement.
 758       *
 759       * @access public
 760       * @param string $hash
 761       */
 762      public function withMGFHash($hash)
 763      {
 764          $new = clone $this;
 765  
 766          // \phpseclib3\Crypt\Hash supports algorithms that PKCS#1 doesn't support.  md5-96 and sha1-96, for example.
 767          switch (strtolower($hash)) {
 768              case 'md2':
 769              case 'md5':
 770              case 'sha1':
 771              case 'sha256':
 772              case 'sha384':
 773              case 'sha512':
 774              case 'sha224':
 775              case 'sha512/224':
 776              case 'sha512/256':
 777                  $new->mgfHash = new Hash($hash);
 778                  break;
 779              default:
 780                  throw new UnsupportedAlgorithmException(
 781                      'The only supported hash algorithms are: md2, md5, sha1, sha256, sha384, sha512, sha224, sha512/224, sha512/256'
 782                  );
 783          }
 784          $new->mgfHLen = $new->mgfHash->getLengthInBytes();
 785  
 786          return $new;
 787      }
 788  
 789      /**
 790       * Returns the MGF hash algorithm currently being used
 791       *
 792       * @access public
 793       */
 794      public function getMGFHash()
 795      {
 796          return clone $this->mgfHash;
 797      }
 798  
 799      /**
 800       * Determines the salt length
 801       *
 802       * Used by RSA::PADDING_PSS
 803       *
 804       * To quote from {@link http://tools.ietf.org/html/rfc3447#page-38 RFC3447#page-38}:
 805       *
 806       *    Typical salt lengths in octets are hLen (the length of the output
 807       *    of the hash function Hash) and 0.
 808       *
 809       * @access public
 810       * @param int $sLen
 811       */
 812      public function withSaltLength($sLen)
 813      {
 814          $new = clone $this;
 815          $new->sLen = $sLen;
 816          return $new;
 817      }
 818  
 819      /**
 820       * Returns the salt length currently being used
 821       *
 822       * @access public
 823       */
 824      public function getSaltLength()
 825      {
 826          return $this->sLen !== null ? $this->sLen : $this->hLen;
 827      }
 828  
 829      /**
 830       * Determines the label
 831       *
 832       * Used by RSA::PADDING_OAEP
 833       *
 834       * To quote from {@link http://tools.ietf.org/html/rfc3447#page-17 RFC3447#page-17}:
 835       *
 836       *    Both the encryption and the decryption operations of RSAES-OAEP take
 837       *    the value of a label L as input.  In this version of PKCS #1, L is
 838       *    the empty string; other uses of the label are outside the scope of
 839       *    this document.
 840       *
 841       * @access public
 842       * @param string $label
 843       */
 844      public function withLabel($label)
 845      {
 846          $new = clone $this;
 847          $new->label = $label;
 848          return $new;
 849      }
 850  
 851      /**
 852       * Returns the label currently being used
 853       *
 854       * @access public
 855       */
 856      public function getLabel()
 857      {
 858          return $this->label;
 859      }
 860  
 861      /**
 862       * Determines the padding modes
 863       *
 864       * Example: $key->withPadding(RSA::ENCRYPTION_PKCS1 | RSA::SIGNATURE_PKCS1);
 865       *
 866       * @access public
 867       * @param int $padding
 868       */
 869      public function withPadding($padding)
 870      {
 871          $masks = [
 872              self::ENCRYPTION_OAEP,
 873              self::ENCRYPTION_PKCS1,
 874              self::ENCRYPTION_NONE
 875          ];
 876          $numSelected = 0;
 877          $selected = 0;
 878          foreach ($masks as $mask) {
 879              if ($padding & $mask) {
 880                  $selected = $mask;
 881                  $numSelected++;
 882              }
 883          }
 884          if ($numSelected > 1) {
 885              throw new InconsistentSetupException('Multiple encryption padding modes have been selected; at most only one should be selected');
 886          }
 887          $encryptionPadding = $selected;
 888  
 889          $masks = [
 890              self::SIGNATURE_PSS,
 891              self::SIGNATURE_RELAXED_PKCS1,
 892              self::SIGNATURE_PKCS1
 893          ];
 894          $numSelected = 0;
 895          $selected = 0;
 896          foreach ($masks as $mask) {
 897              if ($padding & $mask) {
 898                  $selected = $mask;
 899                  $numSelected++;
 900              }
 901          }
 902          if ($numSelected > 1) {
 903              throw new InconsistentSetupException('Multiple signature padding modes have been selected; at most only one should be selected');
 904          }
 905          $signaturePadding = $selected;
 906  
 907          $new = clone $this;
 908          $new->encryptionPadding = $encryptionPadding;
 909          $new->signaturePadding = $signaturePadding;
 910          return $new;
 911      }
 912  
 913      /**
 914       * Returns the padding currently being used
 915       *
 916       * @access public
 917       */
 918      public function getPadding()
 919      {
 920          return $this->signaturePadding | $this->encryptionPadding;
 921      }
 922  
 923      /**
 924       * Returns the current engine being used
 925       *
 926       * OpenSSL is only used in this class (and it's subclasses) for key generation
 927       * Even then it depends on the parameters you're using. It's not used for
 928       * multi-prime RSA nor is it used if the key length is outside of the range
 929       * supported by OpenSSL
 930       *
 931       * @see self::useInternalEngine()
 932       * @see self::useBestEngine()
 933       * @access public
 934       * @return string
 935       */
 936      public function getEngine()
 937      {
 938          if (!isset(self::$engines['PHP'])) {
 939              self::useBestEngine();
 940          }
 941          return self::$engines['OpenSSL'] && self::$defaultExponent == 65537 ?
 942              'OpenSSL' :
 943              'PHP';
 944      }
 945  
 946      /**
 947       * Enable RSA Blinding
 948       *
 949       * @access public
 950       */
 951      public static function enableBlinding()
 952      {
 953          static::$enableBlinding = true;
 954      }
 955  
 956      /**
 957       * Disable RSA Blinding
 958       *
 959       * @access public
 960       */
 961      public static function disableBlinding()
 962      {
 963          static::$enableBlinding = false;
 964      }
 965  }


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