4 * Pure-PHP PKCS#1 (v2.1) compliant implementation of RSA.
8 * Here's an example of how to encrypt and decrypt text with this library:
11 * include 'vendor/autoload.php';
13 * $private = \phpseclib3\Crypt\RSA::createKey();
14 * $public = $private->getPublicKey();
16 * $plaintext = 'terrafrost';
18 * $ciphertext = $public->encrypt($plaintext);
20 * echo $private->decrypt($ciphertext);
24 * Here's an example of how to create signatures and verify signatures with this library:
27 * include 'vendor/autoload.php';
29 * $private = \phpseclib3\Crypt\RSA::createKey();
30 * $public = $private->getPublicKey();
32 * $plaintext = 'terrafrost';
34 * $signature = $private->sign($plaintext);
36 * echo $public->verify($plaintext, $signature) ? 'verified' : 'unverified';
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)
48 * @author Jim Wigginton <terrafrost@php.net>
49 * @copyright 2009 Jim Wigginton
50 * @license http://www.opensource.org/licenses/mit-license.html MIT License
51 * @link http://phpseclib.sourceforge.net
54 namespace phpseclib3\Crypt;
56 use phpseclib3\Crypt\Common\AsymmetricKey;
57 use phpseclib3\Crypt\RSA\Formats\Keys\PSS;
58 use phpseclib3\Crypt\RSA\PrivateKey;
59 use phpseclib3\Crypt\RSA\PublicKey;
60 use phpseclib3\Exception\InconsistentSetupException;
61 use phpseclib3\Exception\UnsupportedAlgorithmException;
62 use phpseclib3\Math\BigInteger;
65 * Pure-PHP PKCS#1 compliant implementation of RSA.
67 * @author Jim Wigginton <terrafrost@php.net>
69 abstract class RSA extends AsymmetricKey
76 const ALGORITHM = 'RSA';
79 * Use {@link http://en.wikipedia.org/wiki/Optimal_Asymmetric_Encryption_Padding Optimal Asymmetric Encryption Padding}
80 * (OAEP) for encryption / decryption.
82 * Uses sha256 by default
84 * @see self::setHash()
85 * @see self::setMGFHash()
86 * @see self::encrypt()
87 * @see self::decrypt()
89 const ENCRYPTION_OAEP = 1;
94 * Although self::PADDING_OAEP / self::PADDING_PSS offers more security, including PKCS#1 padding is necessary for purposes of backwards
95 * compatibility with protocols (like SSH-1) written before OAEP's introduction.
97 * @see self::encrypt()
98 * @see self::decrypt()
100 const ENCRYPTION_PKCS1 = 2;
103 * Do not use any padding
105 * Although this method is not recommended it can none-the-less sometimes be useful if you're trying to decrypt some legacy
106 * stuff, if you're trying to diagnose why an encrypted message isn't decrypting, etc.
108 * @see self::encrypt()
109 * @see self::decrypt()
111 const ENCRYPTION_NONE = 4;
114 * Use the Probabilistic Signature Scheme for signing
116 * Uses sha256 and 0 as the salt length
118 * @see self::setSaltLength()
119 * @see self::setMGFHash()
120 * @see self::setHash()
122 * @see self::verify()
123 * @see self::setHash()
125 const SIGNATURE_PSS = 16;
128 * Use a relaxed version of PKCS#1 padding for signature verification
131 * @see self::verify()
132 * @see self::setHash()
134 const SIGNATURE_RELAXED_PKCS1 = 32;
137 * Use PKCS#1 padding for signature verification
140 * @see self::verify()
141 * @see self::setHash()
143 const SIGNATURE_PKCS1 = 64;
146 * Encryption padding mode
150 protected $encryptionPadding = self::ENCRYPTION_OAEP;
153 * Signature padding mode
157 protected $signaturePadding = self::SIGNATURE_PSS;
160 * Length of hash function output
178 protected $label = '';
181 * Hash function for the Mask Generation Function
183 * @var \phpseclib3\Crypt\Hash
188 * Length of MGF hash function output
197 * @var \phpseclib3\Math\BigInteger
204 * @var \phpseclib3\Math\BigInteger
209 * Exponent (ie. e or d)
211 * @var \phpseclib3\Math\BigInteger
216 * Default public exponent
219 * @link http://en.wikipedia.org/wiki/65537_%28number%29
221 private static $defaultExponent = 65537;
228 protected static $enableBlinding = true;
231 * OpenSSL configuration file name.
233 * @see self::createKey()
236 protected static $configFile;
241 * Per <http://cseweb.ucsd.edu/~hovav/dist/survey.pdf#page=5>, this number ought not result in primes smaller
242 * than 256 bits. As a consequence if the key you're trying to create is 1024 bits and you've set smallestPrime
243 * to 384 bits then you're going to get a 384 bit prime and a 640 bit prime (384 + 1024 % 384). At least if
244 * engine is set to self::ENGINE_INTERNAL. If Engine is set to self::ENGINE_OPENSSL then smallest Prime is
245 * ignored (ie. multi-prime RSA support is more intended as a way to speed up RSA key generation when there's
246 * a chance neither gmp nor OpenSSL are installed)
250 private static $smallestPrime = 4096;
255 * @var \phpseclib3\Math\BigInteger
257 protected $publicExponent;
260 * Sets the public exponent for key generation
262 * This will be 65537 unless changed.
266 public static function setExponent($val)
268 self::$defaultExponent = $val;
272 * Sets the smallest prime number in bits. Used for key generation
274 * This will be 4096 unless changed.
278 public static function setSmallestPrime($val)
280 self::$smallestPrime = $val;
284 * Sets the OpenSSL config file path
286 * Set to the empty string to use the default config file
290 public static function setOpenSSLConfigPath($val)
292 self::$configFile = $val;
296 * Create a private key
298 * The public key can be extracted from the private key
300 * @return RSA\PrivateKey
303 public static function createKey($bits = 2048)
305 self::initialize_static_variables();
307 $class = new \ReflectionClass(static::class);
308 if ($class->isFinal()) {
309 throw new \RuntimeException('createKey() should not be called from final classes (' . static::class . ')');
312 $regSize = $bits >> 1; // divide by two to see how many bits P and Q would be
313 if ($regSize > self::$smallestPrime) {
314 $num_primes = floor($bits / self::$smallestPrime);
315 $regSize = self::$smallestPrime;
320 if ($num_primes == 2 && $bits >= 384 && self::$defaultExponent == 65537) {
321 if (!isset(self::$engines['PHP'])) {
322 self::useBestEngine();
325 // OpenSSL uses 65537 as the exponent and requires RSA keys be 384 bits minimum
326 if (self::$engines['OpenSSL']) {
328 if (self::$configFile) {
329 $config['config'] = self::$configFile;
331 $rsa = openssl_pkey_new(['private_key_bits' => $bits] + $config);
332 openssl_pkey_export($rsa, $privatekeystr, null, $config);
334 // clear the buffer of error strings stemming from a minimalistic openssl.cnf
335 while (openssl_error_string() !== false) {
338 return RSA::load($privatekeystr);
344 $e = new BigInteger(self::$defaultExponent);
347 $n = clone self::$one;
348 $exponents = $coefficients = $primes = [];
350 'top' => clone self::$one,
355 for ($i = 1; $i <= $num_primes; $i++) {
356 if ($i != $num_primes) {
357 $primes[$i] = BigInteger::randomPrime($regSize);
359 extract(BigInteger::minMaxBits($bits));
360 /** @var BigInteger $min
361 * @var BigInteger $max
363 list($min) = $min->divide($n);
364 $min = $min->add(self::$one);
365 list($max) = $max->divide($n);
366 $primes[$i] = BigInteger::randomRangePrime($min, $max);
369 // the first coefficient is calculated differently from the rest
370 // ie. instead of being $primes[1]->modInverse($primes[2]), it's $primes[2]->modInverse($primes[1])
372 $coefficients[$i] = $n->modInverse($primes[$i]);
375 $n = $n->multiply($primes[$i]);
377 $temp = $primes[$i]->subtract(self::$one);
379 // textbook RSA implementations use Euler's totient function instead of the least common multiple.
380 // see http://en.wikipedia.org/wiki/Euler%27s_totient_function
381 $lcm['top'] = $lcm['top']->multiply($temp);
382 $lcm['bottom'] = $lcm['bottom'] === false ? $temp : $lcm['bottom']->gcd($temp);
385 list($temp) = $lcm['top']->divide($lcm['bottom']);
386 $gcd = $temp->gcd($e);
388 } while (!$gcd->equals(self::$one));
390 $coefficients[2] = $primes[2]->modInverse($primes[1]);
392 $d = $e->modInverse($temp);
394 foreach ($primes as $i => $prime) {
395 $temp = $prime->subtract(self::$one);
396 $exponents[$i] = $e->modInverse($temp);
399 // from <http://tools.ietf.org/html/rfc3447#appendix-A.1.2>:
400 // RSAPrivateKey ::= SEQUENCE {
402 // modulus INTEGER, -- n
403 // publicExponent INTEGER, -- e
404 // privateExponent INTEGER, -- d
405 // prime1 INTEGER, -- p
406 // prime2 INTEGER, -- q
407 // exponent1 INTEGER, -- d mod (p-1)
408 // exponent2 INTEGER, -- d mod (q-1)
409 // coefficient INTEGER, -- (inverse of q) mod p
410 // otherPrimeInfos OtherPrimeInfos OPTIONAL
412 $privatekey = new PrivateKey();
413 $privatekey->modulus = $n;
414 $privatekey->k = $bits >> 3;
415 $privatekey->publicExponent = $e;
416 $privatekey->exponent = $d;
417 $privatekey->primes = $primes;
418 $privatekey->exponents = $exponents;
419 $privatekey->coefficients = $coefficients;
422 $publickey = new PublicKey;
423 $publickey->modulus = $n;
424 $publickey->k = $bits >> 3;
425 $publickey->exponent = $e;
426 $publickey->publicExponent = $e;
427 $publickey->isPublic = true;
438 protected static function onLoad(array $components)
440 $key = $components['isPublicKey'] ?
444 $key->modulus = $components['modulus'];
445 $key->publicExponent = $components['publicExponent'];
446 $key->k = $key->modulus->getLengthInBytes();
448 if ($components['isPublicKey'] || !isset($components['privateExponent'])) {
449 $key->exponent = $key->publicExponent;
451 $key->privateExponent = $components['privateExponent'];
452 $key->exponent = $key->privateExponent;
453 $key->primes = $components['primes'];
454 $key->exponents = $components['exponents'];
455 $key->coefficients = $components['coefficients'];
458 if ($components['format'] == PSS::class) {
459 // in the X509 world RSA keys are assumed to use PKCS1 padding by default. only if the key is
460 // explicitly a PSS key is the use of PSS assumed. phpseclib does not work like this. phpseclib
461 // uses PSS padding by default. it assumes the more secure method by default and altho it provides
462 // for the less secure PKCS1 method you have to go out of your way to use it. this is consistent
463 // with the latest trends in crypto. libsodium (NaCl) is actually a little more extreme in that
464 // not only does it defaults to the most secure methods - it doesn't even let you choose less
466 //$key = $key->withPadding(self::SIGNATURE_PSS);
467 if (isset($components['hash'])) {
468 $key = $key->withHash($components['hash']);
470 if (isset($components['MGFHash'])) {
471 $key = $key->withMGFHash($components['MGFHash']);
473 if (isset($components['saltLength'])) {
474 $key = $key->withSaltLength($components['saltLength']);
482 * Initialize static variables
484 protected static function initialize_static_variables()
486 if (!isset(self::$configFile)) {
487 self::$configFile = dirname(__FILE__) . '/../openssl.cnf';
490 parent::initialize_static_variables();
496 * PublicKey and PrivateKey objects can only be created from abstract RSA class
498 protected function __construct()
500 parent::__construct();
502 $this->hLen = $this->hash->getLengthInBytes();
503 $this->mgfHash = new Hash('sha256');
504 $this->mgfHLen = $this->mgfHash->getLengthInBytes();
508 * Integer-to-Octet-String primitive
510 * See {@link http://tools.ietf.org/html/rfc3447#section-4.1 RFC3447#section-4.1}.
512 * @param bool|\phpseclib3\Math\BigInteger $x
514 * @return bool|string
516 protected function i2osp($x, $xLen)
522 if (strlen($x) > $xLen) {
523 throw new \OutOfRangeException('Resultant string length out of range');
525 return str_pad($x, $xLen, chr(0), STR_PAD_LEFT);
529 * Octet-String-to-Integer primitive
531 * See {@link http://tools.ietf.org/html/rfc3447#section-4.2 RFC3447#section-4.2}.
534 * @return \phpseclib3\Math\BigInteger
536 protected function os2ip($x)
538 return new BigInteger($x, 256);
542 * EMSA-PKCS1-V1_5-ENCODE
544 * See {@link http://tools.ietf.org/html/rfc3447#section-9.2 RFC3447#section-9.2}.
548 * @throws \LengthException if the intended encoded message length is too short
551 protected function emsa_pkcs1_v1_5_encode($m, $emLen)
553 $h = $this->hash->hash($m);
555 // see http://tools.ietf.org/html/rfc3447#page-43
556 switch ($this->hash->getHash()) {
558 $t = "\x30\x20\x30\x0c\x06\x08\x2a\x86\x48\x86\xf7\x0d\x02\x02\x05\x00\x04\x10";
561 $t = "\x30\x20\x30\x0c\x06\x08\x2a\x86\x48\x86\xf7\x0d\x02\x05\x05\x00\x04\x10";
564 $t = "\x30\x21\x30\x09\x06\x05\x2b\x0e\x03\x02\x1a\x05\x00\x04\x14";
567 $t = "\x30\x31\x30\x0d\x06\x09\x60\x86\x48\x01\x65\x03\x04\x02\x01\x05\x00\x04\x20";
570 $t = "\x30\x41\x30\x0d\x06\x09\x60\x86\x48\x01\x65\x03\x04\x02\x02\x05\x00\x04\x30";
573 $t = "\x30\x51\x30\x0d\x06\x09\x60\x86\x48\x01\x65\x03\x04\x02\x03\x05\x00\x04\x40";
575 // from https://www.emc.com/collateral/white-papers/h11300-pkcs-1v2-2-rsa-cryptography-standard-wp.pdf#page=40
577 $t = "\x30\x2d\x30\x0d\x06\x09\x60\x86\x48\x01\x65\x03\x04\x02\x04\x05\x00\x04\x1c";
580 $t = "\x30\x2d\x30\x0d\x06\x09\x60\x86\x48\x01\x65\x03\x04\x02\x05\x05\x00\x04\x1c";
583 $t = "\x30\x31\x30\x0d\x06\x09\x60\x86\x48\x01\x65\x03\x04\x02\x06\x05\x00\x04\x20";
588 if ($emLen < $tLen + 11) {
589 throw new \LengthException('Intended encoded message length too short');
592 $ps = str_repeat(chr(0xFF), $emLen - $tLen - 3);
600 * EMSA-PKCS1-V1_5-ENCODE (without NULL)
602 * Quoting https://tools.ietf.org/html/rfc8017#page-65,
604 * "The parameters field associated with id-sha1, id-sha224, id-sha256,
605 * id-sha384, id-sha512, id-sha512/224, and id-sha512/256 should
606 * generally be omitted, but if present, it shall have a value of type
613 protected function emsa_pkcs1_v1_5_encode_without_null($m, $emLen)
615 $h = $this->hash->hash($m);
617 // see http://tools.ietf.org/html/rfc3447#page-43
618 switch ($this->hash->getHash()) {
620 $t = "\x30\x1f\x30\x07\x06\x05\x2b\x0e\x03\x02\x1a\x04\x14";
623 $t = "\x30\x2f\x30\x0b\x06\x09\x60\x86\x48\x01\x65\x03\x04\x02\x01\x04\x20";
626 $t = "\x30\x3f\x30\x0b\x06\x09\x60\x86\x48\x01\x65\x03\x04\x02\x02\x04\x30";
629 $t = "\x30\x4f\x30\x0b\x06\x09\x60\x86\x48\x01\x65\x03\x04\x02\x03\x04\x40";
631 // from https://www.emc.com/collateral/white-papers/h11300-pkcs-1v2-2-rsa-cryptography-standard-wp.pdf#page=40
633 $t = "\x30\x2b\x30\x0b\x06\x09\x60\x86\x48\x01\x65\x03\x04\x02\x04\x04\x1c";
636 $t = "\x30\x2b\x30\x0b\x06\x09\x60\x86\x48\x01\x65\x03\x04\x02\x05\x04\x1c";
639 $t = "\x30\x2f\x30\x0b\x06\x09\x60\x86\x48\x01\x65\x03\x04\x02\x06\x04\x20";
642 throw new UnsupportedAlgorithmException('md2 and md5 require NULLs');
647 if ($emLen < $tLen + 11) {
648 throw new \LengthException('Intended encoded message length too short');
651 $ps = str_repeat(chr(0xFF), $emLen - $tLen - 3);
661 * See {@link http://tools.ietf.org/html/rfc3447#appendix-B.2.1 RFC3447#appendix-B.2.1}.
663 * @param string $mgfSeed
664 * @param int $maskLen
667 protected function mgf1($mgfSeed, $maskLen)
669 // if $maskLen would yield strings larger than 4GB, PKCS#1 suggests a "Mask too long" error be output.
672 $count = ceil($maskLen / $this->mgfHLen);
673 for ($i = 0; $i < $count; $i++) {
675 $t .= $this->mgfHash->hash($mgfSeed . $c);
678 return substr($t, 0, $maskLen);
682 * Returns the key size
684 * More specifically, this returns the size of the modulo in bits.
688 public function getLength()
690 return !isset($this->modulus) ? 0 : $this->modulus->getLength();
694 * Determines which hashing function should be used
696 * Used with signature production / verification and (if the encryption mode is self::PADDING_OAEP) encryption and
699 * @param string $hash
701 public function withHash($hash)
705 // \phpseclib3\Crypt\Hash supports algorithms that PKCS#1 doesn't support. md5-96 and sha1-96, for example.
706 switch (strtolower($hash)) {
716 $new->hash = new Hash($hash);
719 throw new UnsupportedAlgorithmException(
720 'The only supported hash algorithms are: md2, md5, sha1, sha256, sha384, sha512, sha224, sha512/224, sha512/256'
723 $new->hLen = $new->hash->getLengthInBytes();
729 * Determines which hashing function should be used for the mask generation function
731 * The mask generation function is used by self::PADDING_OAEP and self::PADDING_PSS and although it's
732 * best if Hash and MGFHash are set to the same thing this is not a requirement.
734 * @param string $hash
736 public function withMGFHash($hash)
740 // \phpseclib3\Crypt\Hash supports algorithms that PKCS#1 doesn't support. md5-96 and sha1-96, for example.
741 switch (strtolower($hash)) {
751 $new->mgfHash = new Hash($hash);
754 throw new UnsupportedAlgorithmException(
755 'The only supported hash algorithms are: md2, md5, sha1, sha256, sha384, sha512, sha224, sha512/224, sha512/256'
758 $new->mgfHLen = $new->mgfHash->getLengthInBytes();
764 * Returns the MGF hash algorithm currently being used
767 public function getMGFHash()
769 return clone $this->mgfHash;
773 * Determines the salt length
775 * Used by RSA::PADDING_PSS
777 * To quote from {@link http://tools.ietf.org/html/rfc3447#page-38 RFC3447#page-38}:
779 * Typical salt lengths in octets are hLen (the length of the output
780 * of the hash function Hash) and 0.
784 public function withSaltLength($sLen)
792 * Returns the salt length currently being used
795 public function getSaltLength()
797 return $this->sLen !== null ? $this->sLen : $this->hLen;
801 * Determines the label
803 * Used by RSA::PADDING_OAEP
805 * To quote from {@link http://tools.ietf.org/html/rfc3447#page-17 RFC3447#page-17}:
807 * Both the encryption and the decryption operations of RSAES-OAEP take
808 * the value of a label L as input. In this version of PKCS #1, L is
809 * the empty string; other uses of the label are outside the scope of
812 * @param string $label
814 public function withLabel($label)
817 $new->label = $label;
822 * Returns the label currently being used
825 public function getLabel()
831 * Determines the padding modes
833 * Example: $key->withPadding(RSA::ENCRYPTION_PKCS1 | RSA::SIGNATURE_PKCS1);
835 * @param int $padding
837 public function withPadding($padding)
840 self::ENCRYPTION_OAEP,
841 self::ENCRYPTION_PKCS1,
842 self::ENCRYPTION_NONE
846 foreach ($masks as $mask) {
847 if ($padding & $mask) {
852 if ($numSelected > 1) {
853 throw new InconsistentSetupException('Multiple encryption padding modes have been selected; at most only one should be selected');
855 $encryptionPadding = $selected;
859 self::SIGNATURE_RELAXED_PKCS1,
860 self::SIGNATURE_PKCS1
864 foreach ($masks as $mask) {
865 if ($padding & $mask) {
870 if ($numSelected > 1) {
871 throw new InconsistentSetupException('Multiple signature padding modes have been selected; at most only one should be selected');
873 $signaturePadding = $selected;
876 $new->encryptionPadding = $encryptionPadding;
877 $new->signaturePadding = $signaturePadding;
882 * Returns the padding currently being used
885 public function getPadding()
887 return $this->signaturePadding | $this->encryptionPadding;
891 * Returns the current engine being used
893 * OpenSSL is only used in this class (and it's subclasses) for key generation
894 * Even then it depends on the parameters you're using. It's not used for
895 * multi-prime RSA nor is it used if the key length is outside of the range
896 * supported by OpenSSL
898 * @see self::useInternalEngine()
899 * @see self::useBestEngine()
902 public function getEngine()
904 if (!isset(self::$engines['PHP'])) {
905 self::useBestEngine();
907 return self::$engines['OpenSSL'] && self::$defaultExponent == 65537 ?
913 * Enable RSA Blinding
916 public static function enableBlinding()
918 static::$enableBlinding = true;
922 * Disable RSA Blinding
925 public static function disableBlinding()
927 static::$enableBlinding = false;