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 <terrafrost@php.net> 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 56namespace phpseclib3\Crypt; 57 58use phpseclib3\Crypt\Common\AsymmetricKey; 59use phpseclib3\Crypt\RSA\Formats\Keys\PSS; 60use phpseclib3\Crypt\RSA\PrivateKey; 61use phpseclib3\Crypt\RSA\PublicKey; 62use phpseclib3\Exception\InconsistentSetupException; 63use phpseclib3\Exception\UnsupportedAlgorithmException; 64use phpseclib3\Math\BigInteger; 65 66/** 67 * Pure-PHP PKCS#1 compliant implementation of RSA. 68 * 69 * @package RSA 70 * @author Jim Wigginton <terrafrost@php.net> 71 * @access public 72 */ 73abstract 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} 966