[ Index ]

PHP Cross Reference of DokuWiki

title

Body

[close]

/vendor/phpseclib/phpseclib/phpseclib/Crypt/RSA/Formats/Keys/ -> PKCS1.php (source)

   1  <?php
   2  
   3  /**
   4   * PKCS#1 Formatted RSA Key Handler
   5   *
   6   * PHP version 5
   7   *
   8   * Used by File/X509.php
   9   *
  10   * Processes keys with the following headers:
  11   *
  12   * -----BEGIN RSA PRIVATE KEY-----
  13   * -----BEGIN RSA PUBLIC KEY-----
  14   *
  15   * Analogous to ssh-keygen's pem format (as specified by -m)
  16   *
  17   * @author    Jim Wigginton <terrafrost@php.net>
  18   * @copyright 2015 Jim Wigginton
  19   * @license   http://www.opensource.org/licenses/mit-license.html  MIT License
  20   * @link      http://phpseclib.sourceforge.net
  21   */
  22  
  23  namespace phpseclib3\Crypt\RSA\Formats\Keys;
  24  
  25  use phpseclib3\Common\Functions\Strings;
  26  use phpseclib3\Crypt\Common\Formats\Keys\PKCS1 as Progenitor;
  27  use phpseclib3\File\ASN1;
  28  use phpseclib3\File\ASN1\Maps;
  29  use phpseclib3\Math\BigInteger;
  30  
  31  /**
  32   * PKCS#1 Formatted RSA Key Handler
  33   *
  34   * @author  Jim Wigginton <terrafrost@php.net>
  35   */
  36  abstract class PKCS1 extends Progenitor
  37  {
  38      /**
  39       * Break a public or private key down into its constituent components
  40       *
  41       * @param string $key
  42       * @param string $password optional
  43       * @return array
  44       */
  45      public static function load($key, $password = '')
  46      {
  47          if (!Strings::is_stringable($key)) {
  48              throw new \UnexpectedValueException('Key should be a string - not a ' . gettype($key));
  49          }
  50  
  51          if (strpos($key, 'PUBLIC') !== false) {
  52              $components = ['isPublicKey' => true];
  53          } elseif (strpos($key, 'PRIVATE') !== false) {
  54              $components = ['isPublicKey' => false];
  55          } else {
  56              $components = [];
  57          }
  58  
  59          $key = parent::load($key, $password);
  60  
  61          $decoded = ASN1::decodeBER($key);
  62          if (!$decoded) {
  63              throw new \RuntimeException('Unable to decode BER');
  64          }
  65  
  66          $key = ASN1::asn1map($decoded[0], Maps\RSAPrivateKey::MAP);
  67          if (is_array($key)) {
  68              $components += [
  69                  'modulus' => $key['modulus'],
  70                  'publicExponent' => $key['publicExponent'],
  71                  'privateExponent' => $key['privateExponent'],
  72                  'primes' => [1 => $key['prime1'], $key['prime2']],
  73                  'exponents' => [1 => $key['exponent1'], $key['exponent2']],
  74                  'coefficients' => [2 => $key['coefficient']]
  75              ];
  76              if ($key['version'] == 'multi') {
  77                  foreach ($key['otherPrimeInfos'] as $primeInfo) {
  78                      $components['primes'][] = $primeInfo['prime'];
  79                      $components['exponents'][] = $primeInfo['exponent'];
  80                      $components['coefficients'][] = $primeInfo['coefficient'];
  81                  }
  82              }
  83              if (!isset($components['isPublicKey'])) {
  84                  $components['isPublicKey'] = false;
  85              }
  86              return $components;
  87          }
  88  
  89          $key = ASN1::asn1map($decoded[0], Maps\RSAPublicKey::MAP);
  90  
  91          if (!is_array($key)) {
  92              throw new \RuntimeException('Unable to perform ASN1 mapping');
  93          }
  94  
  95          if (!isset($components['isPublicKey'])) {
  96              $components['isPublicKey'] = true;
  97          }
  98  
  99          return $components + $key;
 100      }
 101  
 102      /**
 103       * Convert a private key to the appropriate format.
 104       *
 105       * @param \phpseclib3\Math\BigInteger $n
 106       * @param \phpseclib3\Math\BigInteger $e
 107       * @param \phpseclib3\Math\BigInteger $d
 108       * @param array $primes
 109       * @param array $exponents
 110       * @param array $coefficients
 111       * @param string $password optional
 112       * @param array $options optional
 113       * @return string
 114       */
 115      public static function savePrivateKey(BigInteger $n, BigInteger $e, BigInteger $d, array $primes, array $exponents, array $coefficients, $password = '', array $options = [])
 116      {
 117          $num_primes = count($primes);
 118          $key = [
 119              'version' => $num_primes == 2 ? 'two-prime' : 'multi',
 120              'modulus' => $n,
 121              'publicExponent' => $e,
 122              'privateExponent' => $d,
 123              'prime1' => $primes[1],
 124              'prime2' => $primes[2],
 125              'exponent1' => $exponents[1],
 126              'exponent2' => $exponents[2],
 127              'coefficient' => $coefficients[2]
 128          ];
 129          for ($i = 3; $i <= $num_primes; $i++) {
 130              $key['otherPrimeInfos'][] = [
 131                  'prime' => $primes[$i],
 132                  'exponent' => $exponents[$i],
 133                  'coefficient' => $coefficients[$i]
 134              ];
 135          }
 136  
 137          $key = ASN1::encodeDER($key, Maps\RSAPrivateKey::MAP);
 138  
 139          return self::wrapPrivateKey($key, 'RSA', $password, $options);
 140      }
 141  
 142      /**
 143       * Convert a public key to the appropriate format
 144       *
 145       * @param \phpseclib3\Math\BigInteger $n
 146       * @param \phpseclib3\Math\BigInteger $e
 147       * @return string
 148       */
 149      public static function savePublicKey(BigInteger $n, BigInteger $e)
 150      {
 151          $key = [
 152              'modulus' => $n,
 153              'publicExponent' => $e
 154          ];
 155  
 156          $key = ASN1::encodeDER($key, Maps\RSAPublicKey::MAP);
 157  
 158          return self::wrapPublicKey($key, 'RSA');
 159      }
 160  }