PageRenderTime 82ms CodeModel.GetById 46ms RepoModel.GetById 0ms app.codeStats 1ms

/lib/Phpseclib/Crypt/RSA.php

https://bitbucket.org/appstrakt/lib_php_phpseclib
PHP | 1931 lines | 894 code | 194 blank | 843 comment | 122 complexity | ecaaa9811813fc84cd977049437d9129 MD5 | raw file

Large files files are truncated, but you can click here to view the full file

  1. <?php
  2. /* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */
  3. /**
  4. * Pure-PHP PKCS#1 (v2.1) compliant implementation of RSA.
  5. *
  6. * PHP versions 4 and 5
  7. *
  8. * Here's an example of how to encrypt and decrypt text with this library:
  9. * <code>
  10. * <?php
  11. * include('Crypt/RSA.php');
  12. *
  13. * $rsa = new RSA();
  14. * extract($rsa->createKey());
  15. *
  16. * $plaintext = 'terrafrost';
  17. *
  18. * $rsa->loadKey($privatekey);
  19. * $ciphertext = $rsa->encrypt($plaintext);
  20. *
  21. * $rsa->loadKey($publickey);
  22. * echo $rsa->decrypt($ciphertext);
  23. * ?>
  24. * </code>
  25. *
  26. * Here's an example of how to create signatures and verify signatures with this library:
  27. * <code>
  28. * <?php
  29. * include('Crypt/RSA.php');
  30. *
  31. * $rsa = new RSA();
  32. * extract($rsa->createKey());
  33. *
  34. * $plaintext = 'terrafrost';
  35. *
  36. * $rsa->loadKey($privatekey);
  37. * $signature = $rsa->sign($plaintext);
  38. *
  39. * $rsa->loadKey($publickey);
  40. * echo $rsa->verify($plaintext, $signature) ? 'verified' : 'unverified';
  41. * ?>
  42. * </code>
  43. *
  44. * LICENSE: This library is free software; you can redistribute it and/or
  45. * modify it under the terms of the GNU Lesser General Public
  46. * License as published by the Free Software Foundation; either
  47. * version 2.1 of the License, or (at your option) any later version.
  48. *
  49. * This library is distributed in the hope that it will be useful,
  50. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  51. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  52. * Lesser General Public License for more details.
  53. *
  54. * You should have received a copy of the GNU Lesser General Public
  55. * License along with this library; if not, write to the Free Software
  56. * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
  57. * MA 02111-1307 USA
  58. *
  59. * @category Crypt
  60. * @package RSA
  61. * @author Jim Wigginton <terrafrost@php.net>
  62. * @copyright MMIX Jim Wigginton
  63. * @license http://www.gnu.org/licenses/lgpl.txt
  64. * @version $Id: RSA.php 81 2010-05-19 21:56:16Z admin $
  65. * @link http://phpseclib.sourceforge.net
  66. */
  67. namespace Phpseclib\Crypt;
  68. /**
  69. * Include BigInteger
  70. */
  71. use Phpseclib\Math\BigInteger;
  72. /**
  73. * Include Random
  74. */
  75. /**
  76. * Include Hash
  77. */
  78. /**#@+
  79. * @access public
  80. * @see RSA::encrypt()
  81. * @see RSA::decrypt()
  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 sha1 by default.
  88. *
  89. * @see RSA::setHash()
  90. * @see RSA::setMGFHash()
  91. */
  92. define('CRYPT_RSA_ENCRYPTION_OAEP', 1);
  93. /**
  94. * Use PKCS#1 padding.
  95. *
  96. * Although CRYPT_RSA_ENCRYPTION_OAEP offers more security, including PKCS#1 padding is necessary for purposes of backwards
  97. * compatability with protocols (like SSH-1) written before OAEP's introduction.
  98. */
  99. define('CRYPT_RSA_ENCRYPTION_PKCS1', 2);
  100. /**#@-*/
  101. /**#@+
  102. * @access public
  103. * @see RSA::sign()
  104. * @see RSA::verify()
  105. * @see RSA::setHash()
  106. */
  107. /**
  108. * Use the Probabilistic Signature Scheme for signing
  109. *
  110. * Uses sha1 by default.
  111. *
  112. * @see RSA::setSaltLength()
  113. * @see RSA::setMGFHash()
  114. */
  115. define('CRYPT_RSA_SIGNATURE_PSS', 1);
  116. /**
  117. * Use the PKCS#1 scheme by default.
  118. *
  119. * Although CRYPT_RSA_SIGNATURE_PSS offers more security, including PKCS#1 signing is necessary for purposes of backwards
  120. * compatability with protocols (like SSH-2) written before PSS's introduction.
  121. */
  122. define('CRYPT_RSA_SIGNATURE_PKCS1', 2);
  123. /**#@-*/
  124. /**#@+
  125. * @access private
  126. * @see RSA::createKey()
  127. */
  128. /**
  129. * ASN1 Integer
  130. */
  131. define('CRYPT_RSA_ASN1_INTEGER', 2);
  132. /**
  133. * ASN1 Sequence (with the constucted bit set)
  134. */
  135. define('CRYPT_RSA_ASN1_SEQUENCE', 48);
  136. /**#@-*/
  137. /**#@+
  138. * @access private
  139. * @see RSA::RSA()
  140. */
  141. /**
  142. * To use the pure-PHP implementation
  143. */
  144. define('CRYPT_RSA_MODE_INTERNAL', 1);
  145. /**
  146. * To use the OpenSSL library
  147. *
  148. * (if enabled; otherwise, the internal implementation will be used)
  149. */
  150. define('CRYPT_RSA_MODE_OPENSSL', 2);
  151. /**#@-*/
  152. /**#@+
  153. * @access public
  154. * @see RSA::createKey()
  155. * @see RSA::setPrivateKeyFormat()
  156. */
  157. /**
  158. * PKCS#1 formatted private key
  159. *
  160. * Used by OpenSSH
  161. */
  162. define('CRYPT_RSA_PRIVATE_FORMAT_PKCS1', 0);
  163. /**#@-*/
  164. /**#@+
  165. * @access public
  166. * @see RSA::createKey()
  167. * @see RSA::setPublicKeyFormat()
  168. */
  169. /**
  170. * Raw public key
  171. *
  172. * An array containing two BigInteger objects.
  173. *
  174. * The exponent can be indexed with any of the following:
  175. *
  176. * 0, e, exponent, publicExponent
  177. *
  178. * The modulus can be indexed with any of the following:
  179. *
  180. * 1, n, modulo, modulus
  181. */
  182. define('CRYPT_RSA_PUBLIC_FORMAT_RAW', 1);
  183. /**
  184. * PKCS#1 formatted public key
  185. */
  186. define('CRYPT_RSA_PUBLIC_FORMAT_PKCS1', 2);
  187. /**
  188. * OpenSSH formatted public key
  189. *
  190. * Place in $HOME/.ssh/authorized_keys
  191. */
  192. define('CRYPT_RSA_PUBLIC_FORMAT_OPENSSH', 3);
  193. /**#@-*/
  194. /**
  195. * Pure-PHP PKCS#1 compliant implementation of RSA.
  196. *
  197. * @author Jim Wigginton <terrafrost@php.net>
  198. * @version 0.1.0
  199. * @access public
  200. * @package RSA
  201. */
  202. class RSA {
  203. /**
  204. * Precomputed Zero
  205. *
  206. * @var Array
  207. * @access private
  208. */
  209. var $zero;
  210. /**
  211. * Precomputed One
  212. *
  213. * @var Array
  214. * @access private
  215. */
  216. var $one;
  217. /**
  218. * Private Key Format
  219. *
  220. * @var Integer
  221. * @access private
  222. */
  223. var $privateKeyFormat = CRYPT_RSA_PRIVATE_FORMAT_PKCS1;
  224. /**
  225. * Public Key Format
  226. *
  227. * @var Integer
  228. * @access public
  229. */
  230. var $publicKeyFormat = CRYPT_RSA_PUBLIC_FORMAT_PKCS1;
  231. /**
  232. * Modulus (ie. n)
  233. *
  234. * @var BigInteger
  235. * @access private
  236. */
  237. var $modulus;
  238. /**
  239. * Modulus length
  240. *
  241. * @var BigInteger
  242. * @access private
  243. */
  244. var $k;
  245. /**
  246. * Exponent (ie. e or d)
  247. *
  248. * @var BigInteger
  249. * @access private
  250. */
  251. var $exponent;
  252. /**
  253. * Primes for Chinese Remainder Theorem (ie. p and q)
  254. *
  255. * @var Array
  256. * @access private
  257. */
  258. var $primes;
  259. /**
  260. * Exponents for Chinese Remainder Theorem (ie. dP and dQ)
  261. *
  262. * @var Array
  263. * @access private
  264. */
  265. var $exponents;
  266. /**
  267. * Coefficients for Chinese Remainder Theorem (ie. qInv)
  268. *
  269. * @var Array
  270. * @access private
  271. */
  272. var $coefficients;
  273. /**
  274. * Hash name
  275. *
  276. * @var String
  277. * @access private
  278. */
  279. var $hashName;
  280. /**
  281. * Hash function
  282. *
  283. * @var Hash
  284. * @access private
  285. */
  286. var $hash;
  287. /**
  288. * Length of hash function output
  289. *
  290. * @var Integer
  291. * @access private
  292. */
  293. var $hLen;
  294. /**
  295. * Length of salt
  296. *
  297. * @var Integer
  298. * @access private
  299. */
  300. var $sLen;
  301. /**
  302. * Hash function for the Mask Generation Function
  303. *
  304. * @var Hash
  305. * @access private
  306. */
  307. var $mgfHash;
  308. /**
  309. * Encryption mode
  310. *
  311. * @var Integer
  312. * @access private
  313. */
  314. var $encryptionMode = CRYPT_RSA_ENCRYPTION_OAEP;
  315. /**
  316. * Signature mode
  317. *
  318. * @var Integer
  319. * @access private
  320. */
  321. var $signatureMode = CRYPT_RSA_SIGNATURE_PSS;
  322. /**
  323. * Public Exponent
  324. *
  325. * @var Mixed
  326. * @access private
  327. */
  328. var $publicExponent = false;
  329. /**
  330. * Password
  331. *
  332. * @var String
  333. * @access private
  334. */
  335. var $password = '';
  336. /**
  337. * The constructor
  338. *
  339. * If you want to make use of the openssl extension, you'll need to set the mode manually, yourself. The reason
  340. * RSA doesn't do it is because OpenSSL doesn't fail gracefully. openssl_pkey_new(), in particular, requires
  341. * openssl.cnf be present somewhere and, unfortunately, the only real way to find out is too late.
  342. *
  343. * @return RSA
  344. * @access public
  345. */
  346. function __construct()
  347. {
  348. if ( !defined('CRYPT_RSA_MODE') ) {
  349. switch (true) {
  350. //case extension_loaded('openssl') && version_compare(PHP_VERSION, '4.2.0', '>='):
  351. // define('CRYPT_RSA_MODE', CRYPT_RSA_MODE_OPENSSL);
  352. // break;
  353. default:
  354. define('CRYPT_RSA_MODE', CRYPT_RSA_MODE_INTERNAL);
  355. }
  356. }
  357. $this->zero = new BigInteger();
  358. $this->one = new BigInteger(1);
  359. $this->hash = new Hash('sha1');
  360. $this->hLen = $this->hash->getLength();
  361. $this->hashName = 'sha1';
  362. $this->mgfHash = new Hash('sha1');
  363. }
  364. /**
  365. * Create public / private key pair
  366. *
  367. * Returns an array with the following three elements:
  368. * - 'privatekey': The private key.
  369. * - 'publickey': The public key.
  370. * - 'partialkey': A partially computed key (if the execution time exceeded $timeout).
  371. * Will need to be passed back to RSA::createKey() as the third parameter for further processing.
  372. *
  373. * @access public
  374. * @param optional Integer $bits
  375. * @param optional Integer $timeout
  376. * @param optional BigInteger $p
  377. */
  378. function createKey($bits = 1024, $timeout = false, $primes = array())
  379. {
  380. if ( CRYPT_RSA_MODE == CRYPT_RSA_MODE_OPENSSL ) {
  381. $rsa = openssl_pkey_new(array('private_key_bits' => $bits));
  382. openssl_pkey_export($rsa, $privatekey);
  383. $publickey = openssl_pkey_get_details($rsa);
  384. $publickey = $publickey['key'];
  385. if ($this->privateKeyFormat != CRYPT_RSA_PRIVATE_FORMAT_PKCS1) {
  386. $privatekey = call_user_func_array(array($this, '_convertPrivateKey'), array_values($this->_parseKey($privatekey, CRYPT_RSA_PRIVATE_FORMAT_PKCS1)));
  387. $publickey = call_user_func_array(array($this, '_convertPublicKey'), array_values($this->_parseKey($publickey, CRYPT_RSA_PUBLIC_FORMAT_PKCS1)));
  388. }
  389. return array(
  390. 'privatekey' => $privatekey,
  391. 'publickey' => $publickey,
  392. 'partialkey' => false
  393. );
  394. }
  395. static $e;
  396. if (!isset($e)) {
  397. if (!defined('CRYPT_RSA_EXPONENT')) {
  398. // http://en.wikipedia.org/wiki/65537_%28number%29
  399. define('CRYPT_RSA_EXPONENT', '65537');
  400. }
  401. if (!defined('CRYPT_RSA_COMMENT')) {
  402. define('CRYPT_RSA_COMMENT', 'phpseclib-generated-key');
  403. }
  404. // per <http://cseweb.ucsd.edu/~hovav/dist/survey.pdf#page=5>, this number ought not result in primes smaller
  405. // than 256 bits.
  406. if (!defined('CRYPT_RSA_SMALLEST_PRIME')) {
  407. define('CRYPT_RSA_SMALLEST_PRIME', 4096);
  408. }
  409. $e = new BigInteger(CRYPT_RSA_EXPONENT);
  410. }
  411. extract($this->_generateMinMax($bits));
  412. $absoluteMin = $min;
  413. $temp = $bits >> 1;
  414. if ($temp > CRYPT_RSA_SMALLEST_PRIME) {
  415. $num_primes = floor($bits / CRYPT_RSA_SMALLEST_PRIME);
  416. $temp = CRYPT_RSA_SMALLEST_PRIME;
  417. } else {
  418. $num_primes = 2;
  419. }
  420. extract($this->_generateMinMax($temp + $bits % $temp));
  421. $finalMax = $max;
  422. extract($this->_generateMinMax($temp));
  423. $exponents = $coefficients = array();
  424. $generator = new BigInteger();
  425. $generator->setRandomGenerator('crypt_random');
  426. $n = $this->one->copy();
  427. $lcm = array(
  428. 'top' => $this->one->copy(),
  429. 'bottom' => false
  430. );
  431. $start = time();
  432. $i0 = count($primes) + 1;
  433. do {
  434. for ($i = $i0; $i <= $num_primes; $i++) {
  435. if ($timeout !== false) {
  436. $timeout-= time() - $start;
  437. $start = time();
  438. if ($timeout <= 0) {
  439. return array(
  440. 'privatekey' => '',
  441. 'publickey' => '',
  442. 'partialkey' => $primes
  443. );
  444. }
  445. }
  446. if ($i == $num_primes) {
  447. list($min, $temp) = $absoluteMin->divide($n);
  448. if (!$temp->equals($this->zero)) {
  449. $min = $min->add($this->one); // ie. ceil()
  450. }
  451. $primes[$i] = $generator->randomPrime($min, $finalMax, $timeout);
  452. } else {
  453. $primes[$i] = $generator->randomPrime($min, $max, $timeout);
  454. }
  455. if ($primes[$i] === false) { // if we've reached the timeout
  456. return array(
  457. 'privatekey' => '',
  458. 'publickey' => '',
  459. 'partialkey' => array_slice($primes, 0, $i - 1)
  460. );
  461. }
  462. // the first coefficient is calculated differently from the rest
  463. // ie. instead of being $primes[1]->modInverse($primes[2]), it's $primes[2]->modInverse($primes[1])
  464. if ($i > 2) {
  465. $coefficients[$i] = $n->modInverse($primes[$i]);
  466. }
  467. $n = $n->multiply($primes[$i]);
  468. $temp = $primes[$i]->subtract($this->one);
  469. // textbook RSA implementations use Euler's totient function instead of the least common multiple.
  470. // see http://en.wikipedia.org/wiki/Euler%27s_totient_function
  471. $lcm['top'] = $lcm['top']->multiply($temp);
  472. $lcm['bottom'] = $lcm['bottom'] === false ? $temp : $lcm['bottom']->gcd($temp);
  473. $exponents[$i] = $e->modInverse($temp);
  474. }
  475. list($lcm) = $lcm['top']->divide($lcm['bottom']);
  476. $gcd = $lcm->gcd($e);
  477. $i0 = 1;
  478. } while (!$gcd->equals($this->one));
  479. $d = $e->modInverse($lcm);
  480. $coefficients[2] = $primes[2]->modInverse($primes[1]);
  481. // from <http://tools.ietf.org/html/rfc3447#appendix-A.1.2>:
  482. // RSAPrivateKey ::= SEQUENCE {
  483. // version Version,
  484. // modulus INTEGER, -- n
  485. // publicExponent INTEGER, -- e
  486. // privateExponent INTEGER, -- d
  487. // prime1 INTEGER, -- p
  488. // prime2 INTEGER, -- q
  489. // exponent1 INTEGER, -- d mod (p-1)
  490. // exponent2 INTEGER, -- d mod (q-1)
  491. // coefficient INTEGER, -- (inverse of q) mod p
  492. // otherPrimeInfos OtherPrimeInfos OPTIONAL
  493. // }
  494. return array(
  495. 'privatekey' => $this->_convertPrivateKey($n, $e, $d, $primes, $exponents, $coefficients),
  496. 'publickey' => $this->_convertPublicKey($n, $e),
  497. 'partialkey' => false
  498. );
  499. }
  500. /**
  501. * Convert a private key to the appropriate format.
  502. *
  503. * @access private
  504. * @see setPrivateKeyFormat()
  505. * @param String $RSAPrivateKey
  506. * @return String
  507. */
  508. function _convertPrivateKey($n, $e, $d, $primes, $exponents, $coefficients)
  509. {
  510. $num_primes = count($primes);
  511. $raw = array(
  512. 'version' => $num_primes == 2 ? chr(0) : chr(1), // two-prime vs. multi
  513. 'modulus' => $n->toBytes(true),
  514. 'publicExponent' => $e->toBytes(true),
  515. 'privateExponent' => $d->toBytes(true),
  516. 'prime1' => $primes[1]->toBytes(true),
  517. 'prime2' => $primes[2]->toBytes(true),
  518. 'exponent1' => $exponents[1]->toBytes(true),
  519. 'exponent2' => $exponents[2]->toBytes(true),
  520. 'coefficient' => $coefficients[2]->toBytes(true)
  521. );
  522. // if the format in question does not support multi-prime rsa and multi-prime rsa was used,
  523. // call _convertPublicKey() instead.
  524. switch ($this->privateKeyFormat) {
  525. default: // eg. CRYPT_RSA_PRIVATE_FORMAT_PKCS1
  526. $components = array();
  527. foreach ($raw as $name => $value) {
  528. $components[$name] = pack('Ca*a*', CRYPT_RSA_ASN1_INTEGER, $this->_encodeLength(strlen($value)), $value);
  529. }
  530. $RSAPrivateKey = implode('', $components);
  531. if ($num_primes > 2) {
  532. $OtherPrimeInfos = '';
  533. for ($i = 3; $i <= $num_primes; $i++) {
  534. // OtherPrimeInfos ::= SEQUENCE SIZE(1..MAX) OF OtherPrimeInfo
  535. //
  536. // OtherPrimeInfo ::= SEQUENCE {
  537. // prime INTEGER, -- ri
  538. // exponent INTEGER, -- di
  539. // coefficient INTEGER -- ti
  540. // }
  541. $OtherPrimeInfo = pack('Ca*a*', CRYPT_RSA_ASN1_INTEGER, $this->_encodeLength(strlen($primes[$i]->toBytes(true))), $primes[$i]->toBytes(true));
  542. $OtherPrimeInfo.= pack('Ca*a*', CRYPT_RSA_ASN1_INTEGER, $this->_encodeLength(strlen($exponents[$i]->toBytes(true))), $exponents[$i]->toBytes(true));
  543. $OtherPrimeInfo.= pack('Ca*a*', CRYPT_RSA_ASN1_INTEGER, $this->_encodeLength(strlen($coefficients[$i]->toBytes(true))), $coefficients[$i]->toBytes(true));
  544. $OtherPrimeInfos.= pack('Ca*a*', CRYPT_RSA_ASN1_SEQUENCE, $this->_encodeLength(strlen($OtherPrimeInfo)), $OtherPrimeInfo);
  545. }
  546. $RSAPrivateKey.= pack('Ca*a*', CRYPT_RSA_ASN1_SEQUENCE, $this->_encodeLength(strlen($OtherPrimeInfos)), $OtherPrimeInfos);
  547. }
  548. $RSAPrivateKey = pack('Ca*a*', CRYPT_RSA_ASN1_SEQUENCE, $this->_encodeLength(strlen($RSAPrivateKey)), $RSAPrivateKey);
  549. if (!empty($this->password)) {
  550. $iv = $this->_random(8);
  551. $symkey = pack('H*', md5($this->password . $iv)); // symkey is short for symmetric key
  552. $symkey.= substr(pack('H*', md5($symkey . $this->password . $iv)), 0, 8);
  553. /*if (!class_exists('TripleDES')) {
  554. require_once('Crypt/TripleDES.php');
  555. }*/
  556. $des = new TripleDES();
  557. $des->setKey($symkey);
  558. $des->setIV($iv);
  559. $iv = strtoupper(bin2hex($iv));
  560. $RSAPrivateKey = "-----BEGIN RSA PRIVATE KEY-----\r\n" .
  561. "Proc-Type: 4,ENCRYPTED\r\n" .
  562. "DEK-Info: DES-EDE3-CBC,$iv\r\n" .
  563. "\r\n" .
  564. chunk_split(base64_encode($des->encrypt($RSAPrivateKey))) .
  565. '-----END RSA PRIVATE KEY-----';
  566. } else {
  567. $RSAPrivateKey = "-----BEGIN RSA PRIVATE KEY-----\r\n" .
  568. chunk_split(base64_encode($RSAPrivateKey)) .
  569. '-----END RSA PRIVATE KEY-----';
  570. }
  571. return $RSAPrivateKey;
  572. }
  573. }
  574. /**
  575. * Convert a public key to the appropriate format
  576. *
  577. * @access private
  578. * @see setPublicKeyFormat()
  579. * @param String $RSAPrivateKey
  580. * @return String
  581. */
  582. function _convertPublicKey($n, $e)
  583. {
  584. $modulus = $n->toBytes(true);
  585. $publicExponent = $e->toBytes(true);
  586. switch ($this->publicKeyFormat) {
  587. case CRYPT_RSA_PUBLIC_FORMAT_RAW:
  588. return array('e' => $e->copy(), 'n' => $n->copy());
  589. case CRYPT_RSA_PUBLIC_FORMAT_OPENSSH:
  590. // from <http://tools.ietf.org/html/rfc4253#page-15>:
  591. // string "ssh-rsa"
  592. // mpint e
  593. // mpint n
  594. $RSAPublicKey = pack('Na*Na*Na*', strlen('ssh-rsa'), 'ssh-rsa', strlen($publicExponent), $publicExponent, strlen($modulus), $modulus);
  595. $RSAPublicKey = 'ssh-rsa ' . base64_encode($RSAPublicKey) . ' ' . CRYPT_RSA_COMMENT;
  596. return $RSAPublicKey;
  597. default: // eg. CRYPT_RSA_PUBLIC_FORMAT_PKCS1
  598. // from <http://tools.ietf.org/html/rfc3447#appendix-A.1.1>:
  599. // RSAPublicKey ::= SEQUENCE {
  600. // modulus INTEGER, -- n
  601. // publicExponent INTEGER -- e
  602. // }
  603. $components = array(
  604. 'modulus' => pack('Ca*a*', CRYPT_RSA_ASN1_INTEGER, $this->_encodeLength(strlen($modulus)), $modulus),
  605. 'publicExponent' => pack('Ca*a*', CRYPT_RSA_ASN1_INTEGER, $this->_encodeLength(strlen($publicExponent)), $publicExponent)
  606. );
  607. $RSAPublicKey = pack('Ca*a*a*',
  608. CRYPT_RSA_ASN1_SEQUENCE, $this->_encodeLength(strlen($components['modulus']) + strlen($components['publicExponent'])),
  609. $components['modulus'], $components['publicExponent']
  610. );
  611. $RSAPublicKey = "-----BEGIN PUBLIC KEY-----\r\n" .
  612. chunk_split(base64_encode($RSAPublicKey)) .
  613. '-----END PUBLIC KEY-----';
  614. return $RSAPublicKey;
  615. }
  616. }
  617. /**
  618. * Break a public or private key down into its constituant components
  619. *
  620. * @access private
  621. * @see _convertPublicKey()
  622. * @see _convertPrivateKey()
  623. * @param String $key
  624. * @param Integer $type
  625. * @return Array
  626. */
  627. function _parseKey($key, $type)
  628. {
  629. switch ($type) {
  630. case CRYPT_RSA_PUBLIC_FORMAT_RAW:
  631. if (!is_array($key)) {
  632. return false;
  633. }
  634. $components = array();
  635. switch (true) {
  636. case isset($key['e']):
  637. $components['publicExponent'] = $key['e']->copy();
  638. break;
  639. case isset($key['exponent']):
  640. $components['publicExponent'] = $key['exponent']->copy();
  641. break;
  642. case isset($key['publicExponent']):
  643. $components['publicExponent'] = $key['publicExponent']->copy();
  644. break;
  645. case isset($key[0]):
  646. $components['publicExponent'] = $key[0]->copy();
  647. }
  648. switch (true) {
  649. case isset($key['n']):
  650. $components['modulus'] = $key['n']->copy();
  651. break;
  652. case isset($key['modulo']):
  653. $components['modulus'] = $key['modulo']->copy();
  654. break;
  655. case isset($key['modulus']):
  656. $components['modulus'] = $key['modulus']->copy();
  657. break;
  658. case isset($key[1]):
  659. $components['modulus'] = $key[1]->copy();
  660. }
  661. return $components;
  662. case CRYPT_RSA_PRIVATE_FORMAT_PKCS1:
  663. case CRYPT_RSA_PUBLIC_FORMAT_PKCS1:
  664. /* Although PKCS#1 proposes a format that public and private keys can use, encrypting them is
  665. "outside the scope" of PKCS#1. PKCS#1 then refers you to PKCS#12 and PKCS#15 if you're wanting to
  666. protect private keys, however, that's not what OpenSSL* does. OpenSSL protects private keys by adding
  667. two new "fields" to the key - DEK-Info and Proc-Type. These fields are discussed here:
  668. http://tools.ietf.org/html/rfc1421#section-4.6.1.1
  669. http://tools.ietf.org/html/rfc1421#section-4.6.1.3
  670. DES-EDE3-CBC as an algorithm, however, is not discussed anywhere, near as I can tell.
  671. DES-CBC and DES-EDE are discussed in RFC1423, however, DES-EDE3-CBC isn't, nor is its key derivation
  672. function. As is, the definitive authority on this encoding scheme isn't the IETF but rather OpenSSL's
  673. own implementation. ie. the implementation *is* the standard and any bugs that may exist in that
  674. implementation are part of the standard, as well.
  675. * OpenSSL is the de facto standard. It's utilized by OpenSSH and other projects */
  676. if (preg_match('#DEK-Info: DES-EDE3-CBC,(.+)#', $key, $matches)) {
  677. $iv = pack('H*', trim($matches[1]));
  678. $symkey = pack('H*', md5($this->password . $iv)); // symkey is short for symmetric key
  679. $symkey.= substr(pack('H*', md5($symkey . $this->password . $iv)), 0, 8);
  680. $ciphertext = base64_decode(preg_replace('#.+(\r|\n|\r\n)\1|[\r\n]|-.+-#s', '', $key));
  681. if ($ciphertext === false) {
  682. return false;
  683. }
  684. /*if (!class_exists('Crypt_TripleDES')) {
  685. require_once('Crypt/TripleDES.php');
  686. }*/
  687. $des = new TripleDES();
  688. $des->setKey($symkey);
  689. $des->setIV($iv);
  690. $key = $des->decrypt($ciphertext);
  691. } else {
  692. $key = base64_decode(preg_replace('#-.+-|[\r\n]#', '', $key));
  693. if ($key === false) {
  694. return false;
  695. }
  696. }
  697. $private = false;
  698. $components = array();
  699. $this->_string_shift($key); // skip over CRYPT_RSA_ASN1_SEQUENCE
  700. $this->_decodeLength($key); // skip over the length of the above sequence
  701. $this->_string_shift($key); // skip over CRYPT_RSA_ASN1_INTEGER
  702. $length = $this->_decodeLength($key);
  703. $temp = $this->_string_shift($key, $length);
  704. if (strlen($temp) != 1 || ord($temp) > 2) {
  705. $components['modulus'] = new BigInteger($temp, -256);
  706. $this->_string_shift($key); // skip over CRYPT_RSA_ASN1_INTEGER
  707. $length = $this->_decodeLength($key);
  708. $components[$type == CRYPT_RSA_PUBLIC_FORMAT_PKCS1 ? 'publicExponent' : 'privateExponent'] = new BigInteger($this->_string_shift($key, $length), -256);
  709. return $components;
  710. }
  711. $this->_string_shift($key); // skip over CRYPT_RSA_ASN1_INTEGER
  712. $length = $this->_decodeLength($key);
  713. $components['modulus'] = new BigInteger($this->_string_shift($key, $length), -256);
  714. $this->_string_shift($key);
  715. $length = $this->_decodeLength($key);
  716. $components['publicExponent'] = new BigInteger($this->_string_shift($key, $length), -256);
  717. $this->_string_shift($key);
  718. $length = $this->_decodeLength($key);
  719. $components['privateExponent'] = new BigInteger($this->_string_shift($key, $length), -256);
  720. $this->_string_shift($key);
  721. $length = $this->_decodeLength($key);
  722. $components['primes'] = array(1 => new BigInteger($this->_string_shift($key, $length), -256));
  723. $this->_string_shift($key);
  724. $length = $this->_decodeLength($key);
  725. $components['primes'][] = new BigInteger($this->_string_shift($key, $length), -256);
  726. $this->_string_shift($key);
  727. $length = $this->_decodeLength($key);
  728. $components['exponents'] = array(1 => new BigInteger($this->_string_shift($key, $length), -256));
  729. $this->_string_shift($key);
  730. $length = $this->_decodeLength($key);
  731. $components['exponents'][] = new BigInteger($this->_string_shift($key, $length), -256);
  732. $this->_string_shift($key);
  733. $length = $this->_decodeLength($key);
  734. $components['coefficients'] = array(2 => new BigInteger($this->_string_shift($key, $length), -256));
  735. if (!empty($key)) {
  736. $key = substr($key, 1); // skip over CRYPT_RSA_ASN1_SEQUENCE
  737. $this->_decodeLength($key);
  738. while (!empty($key)) {
  739. $key = substr($key, 1); // skip over CRYPT_RSA_ASN1_SEQUENCE
  740. $this->_decodeLength($key);
  741. $key = substr($key, 1);
  742. $length = $this->_decodeLength($key);
  743. $components['primes'][] = new BigInteger($this->_string_shift($key, $length), -256);
  744. $this->_string_shift($key);
  745. $length = $this->_decodeLength($key);
  746. $components['exponents'][] = new BigInteger($this->_string_shift($key, $length), -256);
  747. $this->_string_shift($key);
  748. $length = $this->_decodeLength($key);
  749. $components['coefficients'][] = new BigInteger($this->_string_shift($key, $length), -256);
  750. }
  751. }
  752. return $components;
  753. case CRYPT_RSA_PUBLIC_FORMAT_OPENSSH:
  754. $key = base64_decode(preg_replace('#^ssh-rsa | .+$#', '', $key));
  755. if ($key === false) {
  756. return false;
  757. }
  758. $components = array();
  759. extract(unpack('Nlength', $this->_string_shift($key, 4)));
  760. $components['modulus'] = new BigInteger($this->_string_shift($key, $length), -256);
  761. extract(unpack('Nlength', $this->_string_shift($key, 4)));
  762. $components['publicExponent'] = new BigInteger($this->_string_shift($key, $length), -256);
  763. return $components;
  764. }
  765. }
  766. /**
  767. * Loads a public or private key
  768. *
  769. * @access public
  770. * @param String $key
  771. * @param Integer $type optional
  772. */
  773. function loadKey($key, $type = CRYPT_RSA_PRIVATE_FORMAT_PKCS1)
  774. {
  775. $components = $this->_parseKey($key, $type);
  776. $this->modulus = $components['modulus'];
  777. $this->k = strlen($this->modulus->toBytes());
  778. $this->exponent = isset($components['privateExponent']) ? $components['privateExponent'] : $components['publicExponent'];
  779. if (isset($components['primes'])) {
  780. $this->primes = $components['primes'];
  781. $this->exponents = $components['exponents'];
  782. $this->coefficients = $components['coefficients'];
  783. $this->publicExponent = $components['publicExponent'];
  784. } else {
  785. $this->primes = array();
  786. $this->exponents = array();
  787. $this->coefficients = array();
  788. $this->publicExponent = false;
  789. }
  790. }
  791. /**
  792. * Sets the password
  793. *
  794. * Private keys can be encrypted with a password. To unset the password, pass in the empty string or false.
  795. * Or rather, pass in $password such that empty($password) is true.
  796. *
  797. * @see createKey()
  798. * @see loadKey()
  799. * @access public
  800. * @param String $password
  801. */
  802. function setPassword($password)
  803. {
  804. $this->password = $password;
  805. }
  806. /**
  807. * Defines the public key
  808. *
  809. * Some private key formats define the public exponent and some don't. Those that don't define it are problematic when
  810. * used in certain contexts. For example, in SSH-2, RSA authentication works by sending the public key along with a
  811. * message signed by the private key to the server. The SSH-2 server looks the public key up in an index of public keys
  812. * and if it's present then proceeds to verify the signature. Problem is, if your private key doesn't include the public
  813. * exponent this won't work unless you manually add the public exponent.
  814. *
  815. * Do note that when a new key is loaded the index will be cleared.
  816. *
  817. * Returns true on success, false on failure
  818. *
  819. * @see getPublicKey()
  820. * @access public
  821. * @param String $key
  822. * @param Integer $type optional
  823. * @return Boolean
  824. */
  825. function setPublicKey($key, $type = CRYPT_RSA_PUBLIC_FORMAT_PKCS1)
  826. {
  827. $components = $this->_parseKey($key, $type);
  828. if (!$this->modulus->equals($components['modulus'])) {
  829. return false;
  830. }
  831. $this->publicExponent = $components['publicExponent'];
  832. }
  833. /**
  834. * Returns the public key
  835. *
  836. * The public key is only returned under two circumstances - if the private key had the public key embedded within it
  837. * or if the public key was set via setPublicKey(). If the currently loaded key is supposed to be the public key this
  838. * function won't return it since this library, for the most part, doesn't distinguish between public and private keys.
  839. *
  840. * @see getPublicKey()
  841. * @access public
  842. * @param String $key
  843. * @param Integer $type optional
  844. */
  845. function getPublicKey($type = CRYPT_RSA_PUBLIC_FORMAT_PKCS1)
  846. {
  847. $oldFormat = $this->publicKeyFormat;
  848. $this->publicKeyFormat = $type;
  849. $temp = $this->_convertPublicKey($this->modulus, $this->publicExponent);
  850. $this->publicKeyFormat = $oldFormat;
  851. return $temp;
  852. }
  853. /**
  854. * Generates the smallest and largest numbers requiring $bits bits
  855. *
  856. * @access private
  857. * @param Integer $bits
  858. * @return Array
  859. */
  860. function _generateMinMax($bits)
  861. {
  862. $bytes = $bits >> 3;
  863. $min = str_repeat(chr(0), $bytes);
  864. $max = str_repeat(chr(0xFF), $bytes);
  865. $msb = $num_bits & 7;
  866. if ($msb) {
  867. $min = chr(1 << ($msb - 1)) . $min;
  868. $max = chr((1 << $msb) - 1) . $max;
  869. } else {
  870. $min[0] = chr(0x80);
  871. }
  872. return array(
  873. 'min' => new BigInteger($min, 256),
  874. 'max' => new BigInteger($max, 256)
  875. );
  876. }
  877. /**
  878. * DER-decode the length
  879. *
  880. * DER supports lengths up to (2**8)**127, however, we'll only support lengths up to (2**8)**4. See
  881. * {@link http://itu.int/ITU-T/studygroups/com17/languages/X.690-0207.pdf#p=13 X.690 § 8.1.3} for more information.
  882. *
  883. * @access private
  884. * @param String $string
  885. * @return Integer
  886. */
  887. function _decodeLength(&$string)
  888. {
  889. $length = ord($this->_string_shift($string));
  890. $start = 0;
  891. if ( $length & 0x80 ) { // definite length, long form
  892. $length&= 0x7F;
  893. $temp = $this->_string_shift($string, $length);
  894. $start+= $length;
  895. list(, $length) = unpack('N', substr(str_pad($temp, 4, chr(0), STR_PAD_LEFT), -4));
  896. }
  897. return $length;
  898. }
  899. /**
  900. * DER-encode the length
  901. *
  902. * DER supports lengths up to (2**8)**127, however, we'll only support lengths up to (2**8)**4. See
  903. * {@link http://itu.int/ITU-T/studygroups/com17/languages/X.690-0207.pdf#p=13 X.690 § 8.1.3} for more information.
  904. *
  905. * @access private
  906. * @param Integer $length
  907. * @return String
  908. */
  909. function _encodeLength($length)
  910. {
  911. if ($length <= 0x7F) {
  912. return chr($length);
  913. }
  914. $temp = ltrim(pack('N', $length), chr(0));
  915. return pack('Ca*', 0x80 | strlen($temp), $temp);
  916. }
  917. /**
  918. * String Shift
  919. *
  920. * Inspired by array_shift
  921. *
  922. * @param String $string
  923. * @param optional Integer $index
  924. * @return String
  925. * @access private
  926. */
  927. function _string_shift(&$string, $index = 1)
  928. {
  929. $substr = substr($string, 0, $index);
  930. $string = substr($string, $index);
  931. return $substr;
  932. }
  933. /**
  934. * Determines the private key format
  935. *
  936. * @see createKey()
  937. * @access public
  938. * @param Integer $format
  939. */
  940. function setPrivateKeyFormat($format)
  941. {
  942. $this->privateKeyFormat = $format;
  943. }
  944. /**
  945. * Determines the public key format
  946. *
  947. * @see createKey()
  948. * @access public
  949. * @param Integer $format
  950. */
  951. function setPublicKeyFormat($format)
  952. {
  953. $this->publicKeyFormat = $format;
  954. }
  955. /**
  956. * Determines which hashing function should be used
  957. *
  958. * Used with signature production / verification and (if the encryption mode is CRYPT_RSA_ENCRYPTION_OAEP) encryption and
  959. * decryption. If $hash isn't supported, sha1 is used.
  960. *
  961. * @access public
  962. * @param String $hash
  963. */
  964. function setHash($hash)
  965. {
  966. // Hash supports algorithms that PKCS#1 doesn't support. md5-96 and sha1-96, for example.
  967. switch ($hash) {
  968. case 'md2':
  969. case 'md5':
  970. case 'sha1':
  971. case 'sha256':
  972. case 'sha384':
  973. case 'sha512':
  974. $this->hash = new Hash($hash);
  975. $this->hLen = $this->hash->getLength();
  976. $this->hashName = $hash;
  977. break;
  978. default:
  979. $this->hash = new Hash('sha1');
  980. $this->hLen = $this->hash->getLength();
  981. $this->hashName = 'sha1';
  982. }
  983. }
  984. /**
  985. * Determines which hashing function should be used for the mask generation function
  986. *
  987. * The mask generation function is used by CRYPT_RSA_ENCRYPTION_OAEP and CRYPT_RSA_SIGNATURE_PSS and although it's
  988. * best if Hash and MGFHash are set to the same thing this is not a requirement.
  989. *
  990. * @access public
  991. * @param String $hash
  992. */
  993. function setMGFHash($hash)
  994. {
  995. // Hash supports algorithms that PKCS#1 doesn't support. md5-96 and sha1-96, for example.
  996. switch ($hash) {
  997. case 'md2':
  998. case 'md5':
  999. case 'sha1':
  1000. case 'sha256':
  1001. case 'sha384':
  1002. case 'sha512':
  1003. $this->mgfHash = new Hash($hash);
  1004. break;
  1005. default:
  1006. $this->mgfHash = new Hash('sha1');
  1007. }
  1008. }
  1009. /**
  1010. * Determines the salt length
  1011. *
  1012. * To quote from {@link http://tools.ietf.org/html/rfc3447#page-38 RFC3447#page-38}:
  1013. *
  1014. * Typical salt lengths in octets are hLen (the length of the output
  1015. * of the hash function Hash) and 0.
  1016. *
  1017. * @access public
  1018. * @param Integer $format
  1019. */
  1020. function setSaltLength($sLen)
  1021. {
  1022. $this->sLen = $sLen;
  1023. }
  1024. /**
  1025. * Generates a random string x bytes long
  1026. *
  1027. * @access public
  1028. * @param Integer $bytes
  1029. * @param optional Integer $nonzero
  1030. * @return String
  1031. */
  1032. function _random($bytes, $nonzero = false)
  1033. {
  1034. $temp = '';
  1035. if ($nonzero) {
  1036. for ($i = 0; $i < $bytes; $i++) {
  1037. $temp.= chr(crypt_random(1, 255));
  1038. }
  1039. } else {
  1040. $ints = ($bytes + 1) >> 2;
  1041. for ($i = 0; $i < $ints; $i++) {
  1042. $temp.= pack('N', crypt_random());
  1043. }
  1044. $temp = substr($temp, 0, $bytes);
  1045. }
  1046. return $temp;
  1047. }
  1048. /**
  1049. * Integer-to-Octet-String primitive
  1050. *
  1051. * See {@link http://tools.ietf.org/html/rfc3447#section-4.1 RFC3447#section-4.1}.
  1052. *
  1053. * @access private
  1054. * @param BigInteger $x
  1055. * @param Integer $xLen
  1056. * @return String
  1057. */
  1058. function _i2osp($x, $xLen)
  1059. {
  1060. $x = $x->toBytes();
  1061. if (strlen($x) > $xLen) {
  1062. user_error('Integer too large', E_USER_NOTICE);
  1063. return false;
  1064. }
  1065. return str_pad($x, $xLen, chr(0), STR_PAD_LEFT);
  1066. }
  1067. /**
  1068. * Octet-String-to-Integer primitive
  1069. *
  1070. * See {@link http://tools.ietf.org/html/rfc3447#section-4.2 RFC3447#section-4.2}.
  1071. *
  1072. * @access private
  1073. * @param String $x
  1074. * @return BigInteger
  1075. */
  1076. function _os2ip($x)
  1077. {
  1078. return new BigInteger($x, 256);
  1079. }
  1080. /**
  1081. * Exponentiate with or without Chinese Remainder Theorem
  1082. *
  1083. * See {@link http://tools.ietf.org/html/rfc3447#section-5.1.1 RFC3447#section-5.1.2}.
  1084. *
  1085. * @access private
  1086. * @param BigInteger $x
  1087. * @return BigInteger
  1088. */
  1089. function _exponentiate($x)
  1090. {
  1091. if (empty($this->primes) || empty($this->coefficients) || empty($this->exponents)) {
  1092. return $x->modPow($this->exponent, $this->modulus);
  1093. }
  1094. $num_primes = count($this->primes);
  1095. $m_i = array(
  1096. 1 => $x->modPow($this->exponents[1], $this->primes[1]),
  1097. 2 => $x->modPow($this->exponents[2], $this->primes[2])
  1098. );
  1099. $h = $m_i[1]->subtract($m_i[2]);
  1100. $h = $h->multiply($this->coefficients[2]);
  1101. list(, $h) = $h->divide($this->primes[1]);
  1102. $m = $m_i[2]->add($h->multiply($this->primes[2]));
  1103. $r = $this->primes[1];
  1104. for ($i = 3; $i <= $num_primes; $i++) {
  1105. $m_i = $x->modPow($this->exponents[$i], $this->primes[$i]);
  1106. $r = $r->multiply($this->primes[$i - 1]);
  1107. $h = $m_i->subtract($m);
  1108. $h = $h->multiply($this->coefficients[$i]);
  1109. list(, $h) = $h->divide($this->primes[$i]);
  1110. $m = $m->add($r->multiply($h));
  1111. }
  1112. return $m;
  1113. }
  1114. /**
  1115. * RSAEP
  1116. *
  1117. * See {@link http://tools.ietf.org/html/rfc3447#section-5.1.1 RFC3447#section-5.1.1}.
  1118. *
  1119. * @access private
  1120. * @param BigInteger $m
  1121. * @return BigInteger
  1122. */
  1123. function _rsaep($m)
  1124. {
  1125. if ($m->compare($this->zero) < 0 || $m->compare($this->modulus) > 0) {
  1126. user_error('Message representative out of range', E_USER_NOTICE);
  1127. return false;
  1128. }
  1129. return $this->_exponentiate($m);
  1130. }
  1131. /**
  1132. * RSADP
  1133. *
  1134. * See {@link http://tools.ietf.org/html/rfc3447#section-5.1.2 RFC3447#section-5.1.2}.
  1135. *
  1136. * @access private
  1137. * @param BigInteger $c
  1138. * @return BigInteger
  1139. */
  1140. function _rsadp($c)
  1141. {
  1142. if ($c->compare($this->zero) < 0 || $c->compare($this->modulus) > 0) {
  1143. user_error('Ciphertext representative out of range', E_USER_NOTICE);
  1144. return false;
  1145. }
  1146. return $this->_exponentiate($c);
  1147. }
  1148. /**
  1149. * RSASP1
  1150. *
  1151. * See {@link http://tools.ietf.org/html/rfc3447#section-5.2.1 RFC3447#section-5.2.1}.
  1152. *
  1153. * @access private
  1154. * @param BigInteger $m
  1155. * @return BigInteger
  1156. */
  1157. function _rsasp1($m)
  1158. {
  1159. if ($m->compare($this->zero) < 0 || $m->compare($this->modulus) > 0) {
  1160. user_error('Message representative out of range', E_USER_NOTICE);
  1161. return false;
  1162. }
  1163. return $this->_exponentiate($m);
  1164. }
  1165. /**
  1166. * RSAVP1
  1167. *
  1168. * See {@link http://tools.ietf.org/html/rfc3447#section-5.2.2 RFC3447#section-5.2.2}.
  1169. *
  1170. * @access private
  1171. * @param BigInteger $s
  1172. * @return BigInteger
  1173. */
  1174. function _rsavp1($s)
  1175. {
  1176. if ($s->compare($this->zero) < 0 || $s->compare($this->modulus) > 0) {
  1177. user_error('Signature representative out of range', E_USER_NOTICE);
  1178. return false;
  1179. }
  1180. return $this->_exponentiate($s);
  1181. }
  1182. /**
  1183. * MGF1
  1184. *
  1185. * See {@link http://tools.ietf.org/html/rfc3447#section-B.2.1 RFC3447#section-B.2.1}.
  1186. *
  1187. * @access private
  1188. * @param String $mgfSeed
  1189. * @param Integer $mgfLen
  1190. * @return String
  1191. */
  1192. function _mgf1($mgfSeed, $maskLen)
  1193. {
  1194. // if $maskLen would yield strings larger than 4GB, PKCS#1 suggests a "Mask too long" error be output.
  1195. $t = '';
  1196. $count = ceil($maskLen / $this->hLen);
  1197. for ($i = 0; $i < $count; $i++) {
  1198. $c = pack('N', $i);
  1199. $t.= $this->mgfHash->hash($mgfSeed . $c);
  1200. }
  1201. return substr($t, 0, $maskLen);
  1202. }
  1203. /**
  1204. * RSAES-OAEP-ENCRYPT
  1205. *
  1206. * See {@link http://tools.ietf.org/html/rfc3447#section-7.1.1 RFC3447#section-7.1.1} and
  1207. * {http://en.wikipedia.org/wiki/Optimal_Asymmetric_Encryption_Padding OAES}.
  1208. *
  1209. * @access private
  1210. * @param String $m
  1211. * @param String $l
  1212. * @return String
  1213. */
  1214. function _rsaes_oaep_encrypt($m, $l = '')
  1215. {
  1216. $mLen = strlen($m);
  1217. // Length checking
  1218. // if $l is larger than two million terrabytes and you're using sha1, PKCS#1 suggests a "Label too long" error
  1219. // be output.
  1220. if ($mLen > $this->k - 2 * $this->hLen - 2) {
  1221. user_error('Message too long', E_USER_NOTICE);
  1222. return false;
  1223. }
  1224. // EME-OAEP encoding
  1225. $lHash = $this->hash->hash($l);
  1226. $ps = str_repeat(chr(0), $this->k - $mLen - 2 * $this->hLen - 2);
  1227. $db = $lHash . $ps . chr(1) . $m;
  1228. $seed = $this->_random($this->hLen);
  1229. $dbMask = $this->_mgf1($seed, $this->k - $this->hLen - 1);
  1230. $maskedDB = $db ^ $dbMask;
  1231. $seedMask = $this->_mgf1($maskedDB, $this->hLen);
  1232. $maskedSeed = $seed ^ $seedMask;
  1233. $em = chr(0) . $maskedSeed . $maskedDB;
  1234. // RSA encryption
  1235. $m = $this->_os2ip($em);
  1236. $c = $this->_rsaep($m);
  1237. $c = $this->_i2osp($c, $this->k);
  1238. // Output the ciphertext C
  1239. return $c;
  1240. }
  1241. /**
  1242. * RSAES-OAEP-DECRYPT
  1243. *
  1244. * See {@link http://tools.ietf.org/html/rfc3447#section-7.1.2 RFC3447#section-7.1.2}. The fact that the error
  1245. * messages aren't distinguishable from one another hinders debugging, but, to quote from RFC3447#section-7.1.2:
  1246. *
  1247. * Note. Care must be taken to ensure that an opponent cannot
  1248. * distinguish the different error conditions in Step 3.g, whether by
  1249. * error message or timing, or, more generally, learn partial
  1250. * information about the encoded message EM. Otherwise an opponent may
  1251. * be able to obtain useful information about the decryption of the
  1252. * ciphertext C, leading to a chosen-ciphertext attack such as the one
  1253. * observed by Manger [36].
  1254. *
  1255. * As for $l... to quote from {@link http://tools.ietf.org/html/rfc3447#page-17 RFC3447#page-17}:
  1256. *
  1257. * Both the encryption and the decryption operations of RSAES-OAEP take
  1258. * the value of a label L as input. In this version of PKCS #1, L is
  1259. * the empty string; other uses of the label are outside the scope of
  1260. * this document.
  1261. *
  1262. * @access private
  1263. * @param String $c
  1264. * @param String $l
  1265. * @return String
  1266. */
  1267. function _rsaes_oaep_decrypt($c, $l = '')
  1268. {
  1269. // Length checking
  1270. // if $l is larger than two million terrabytes and you're using sha1, PKCS#1 suggests a "Label too long" error
  1271. // be output.
  1272. if (strlen($c) != $this->k || $this->k < 2 * $this->hLen + 2) {
  1273. user_error('Decryption error', E_USER_NOTICE);
  1274. return false;
  1275. }
  1276. // RSA decryption
  1277. $c = $this->_os2ip($c);
  1278. $m = $this->_rsadp($c);
  1279. if ($m === false) {
  1280. user_error('Decryption error', E_USER_NOTICE);
  1281. return false;
  1282. }
  1283. $em = $this->_i2osp($m, $this->k);
  1284. // EME-OAEP decoding
  1285. $lHash = $this->hash->hash($l);
  1286. $y = ord($em[0]);
  1287. $maskedSeed = substr($em, 1, $this->hLen);
  1288. $maskedDB = substr($em, $this->hLen + 1);
  1289. $seedMask = $this->_mgf1($maskedDB, $this->hLen);
  1290. $seed = $maskedSeed ^ $seedMask;
  1291. $dbMask = $this->_mgf1($seed, $this->k - $this->hLen - 1);
  1292. $db = $maskedDB ^ $dbMask;
  1293. $lHash2 = substr($db, 0, $this->hLen);
  1294. $m = substr($db, $this->hLen);
  1295. if ($lHash != $lHash2) {
  1296. user_error('Decryption error', E_USER_NOTICE);
  1297. return false;
  1298. }
  1299. $m = ltrim($m, chr(0));
  1300. if (ord($m[0]) != 1) {
  1301. user_error('Decryption error', E_USER_NOTICE);
  1302. return false;
  1303. }
  1304. // Output the message M
  1305. return substr($m, 1);
  1306. }
  1307. /**
  1308. * RSAES-PKCS1-V1_5-ENCRYPT
  1309. *
  1310. * See {@link http://tools.ietf.org/html/rfc3447#section-7.2.1 RFC3447#section-7.2.1}.
  1311. *
  1312. * @access private
  1313. * @param String $m
  1314. * @return String
  1315. */
  1316. function _rsaes_pkcs1_v1_5_encrypt($m)
  1317. {
  1318. $mLen = strlen($m);
  1319. // Length checking
  1320. if ($mLen > $this->k - 11) {
  1321. user_error('Message too long', E_USER_NOTICE);
  1322. return false;
  1323. }
  1324. // EME-PKCS1-v1_5 encoding
  1325. $ps = $this->_random($this->k - $mLen - 3, true);
  1326. $em = chr(0) . chr(2) . $ps . chr(0) . $m;
  1327. // RSA encryption
  1328. $m = $this->_os2ip($em);
  1329. $c = $this->_rsaep($m);
  1330. $c = $this->_i2osp($c, $this->k);
  1331. // Output the ciphertext C
  1332. return $c;
  1333. }
  1334. /**
  1335. * RSAES-PKCS1-V1_5-DECRYPT
  1336. *
  1337. * See {@link http://tools.ietf.org/html/rfc3447#section-7.2.2 RFC3447#section-7.2.2}.
  1338. *
  1339. * @access private
  1340. * @param String $c
  1341. * @return String
  1342. */
  1343. function _rsaes_pkcs1_v1_5_decrypt($c)
  1344. {
  1345. // Length checking
  1346. if (strlen($c) != $this->k) { // or if k < 11
  1347. user_error('Decryption error', E_USER_NOTICE);
  1348. return false;
  1349. }
  1350. // RSA decryption
  1351. $c = $this->_os2ip($c);
  1352. $m = $this->_rsadp($c);
  1353. if ($m === false) {
  1354. user_error('Decryption error', E_USER_NOTICE);
  1355. return false;
  1356. }
  1357. $em = $this->_i2osp($m, $this->k);
  1358. // EME-PKCS1-v1_5 decoding
  1359. if (ord($em[0]) != 0 || ord($em[1]) != 2) {
  1360. user_error('Decryption error', E_USER_NOTICE);
  1361. return false;
  1362. }
  1363. $ps = substr($em, 2, strpos($em, chr(0), 2) - 2);
  1364. $m = substr($em, strlen($ps) + 3);
  1365. if (strlen($ps) < 8) {
  1366. user_error('Decryption error', E_USER_NOTICE);
  1367. return false;
  1368. }
  1369. // Output M
  1370. return $m;
  1371. }
  1372. /**
  1373. * EMSA-PSS-ENCODE
  1374. *
  1375. * See {@link http://tools.ietf.org/html/rfc3447#section-9.1.1 RFC3447#section-9.1.1}.
  1376. *
  1377. …

Large files files are truncated, but you can click here to view the full file