[ Index ]

PHP Cross Reference of DokuWiki

title

Body

[close]

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

   1  <?php
   2  
   3  /**
   4   * JSON Web Key (RFC7517) Formatted RSA Handler
   5   *
   6   * PHP version 5
   7   *
   8   * @author    Jim Wigginton <terrafrost@php.net>
   9   * @copyright 2015 Jim Wigginton
  10   * @license   http://www.opensource.org/licenses/mit-license.html  MIT License
  11   * @link      http://phpseclib.sourceforge.net
  12   */
  13  
  14  namespace phpseclib3\Crypt\RSA\Formats\Keys;
  15  
  16  use phpseclib3\Common\Functions\Strings;
  17  use phpseclib3\Crypt\Common\Formats\Keys\JWK as Progenitor;
  18  use phpseclib3\Math\BigInteger;
  19  
  20  /**
  21   * JWK Formatted RSA Handler
  22   *
  23   * @author  Jim Wigginton <terrafrost@php.net>
  24   */
  25  abstract class JWK extends Progenitor
  26  {
  27      /**
  28       * Break a public or private key down into its constituent components
  29       *
  30       * @param string $key
  31       * @param string $password optional
  32       * @return array
  33       */
  34      public static function load($key, $password = '')
  35      {
  36          $key = parent::load($key, $password);
  37  
  38          if ($key->kty != 'RSA') {
  39              throw new \RuntimeException('Only RSA JWK keys are supported');
  40          }
  41  
  42          $count = $publicCount = 0;
  43          $vars = ['n', 'e', 'd', 'p', 'q', 'dp', 'dq', 'qi'];
  44          foreach ($vars as $var) {
  45              if (!isset($key->$var) || !is_string($key->$var)) {
  46                  continue;
  47              }
  48              $count++;
  49              $value = new BigInteger(Strings::base64url_decode($key->$var), 256);
  50              switch ($var) {
  51                  case 'n':
  52                      $publicCount++;
  53                      $components['modulus'] = $value;
  54                      break;
  55                  case 'e':
  56                      $publicCount++;
  57                      $components['publicExponent'] = $value;
  58                      break;
  59                  case 'd':
  60                      $components['privateExponent'] = $value;
  61                      break;
  62                  case 'p':
  63                      $components['primes'][1] = $value;
  64                      break;
  65                  case 'q':
  66                      $components['primes'][2] = $value;
  67                      break;
  68                  case 'dp':
  69                      $components['exponents'][1] = $value;
  70                      break;
  71                  case 'dq':
  72                      $components['exponents'][2] = $value;
  73                      break;
  74                  case 'qi':
  75                      $components['coefficients'][2] = $value;
  76              }
  77          }
  78  
  79          if ($count == count($vars)) {
  80              return $components + ['isPublicKey' => false];
  81          }
  82  
  83          if ($count == 2 && $publicCount == 2) {
  84              return $components + ['isPublicKey' => true];
  85          }
  86  
  87          throw new \UnexpectedValueException('Key does not have an appropriate number of RSA parameters');
  88      }
  89  
  90      /**
  91       * Convert a private key to the appropriate format.
  92       *
  93       * @param \phpseclib3\Math\BigInteger $n
  94       * @param \phpseclib3\Math\BigInteger $e
  95       * @param \phpseclib3\Math\BigInteger $d
  96       * @param array $primes
  97       * @param array $exponents
  98       * @param array $coefficients
  99       * @param string $password optional
 100       * @param array $options optional
 101       * @return string
 102       */
 103      public static function savePrivateKey(BigInteger $n, BigInteger $e, BigInteger $d, array $primes, array $exponents, array $coefficients, $password = '', array $options = [])
 104      {
 105          if (count($primes) != 2) {
 106              throw new \InvalidArgumentException('JWK does not support multi-prime RSA keys');
 107          }
 108  
 109          $key = [
 110              'kty' => 'RSA',
 111              'n' => Strings::base64url_encode($n->toBytes()),
 112              'e' => Strings::base64url_encode($e->toBytes()),
 113              'd' => Strings::base64url_encode($d->toBytes()),
 114              'p' => Strings::base64url_encode($primes[1]->toBytes()),
 115              'q' => Strings::base64url_encode($primes[2]->toBytes()),
 116              'dp' => Strings::base64url_encode($exponents[1]->toBytes()),
 117              'dq' => Strings::base64url_encode($exponents[2]->toBytes()),
 118              'qi' => Strings::base64url_encode($coefficients[2]->toBytes())
 119          ];
 120  
 121          return self::wrapKey($key, $options);
 122      }
 123  
 124      /**
 125       * Convert a public key to the appropriate format
 126       *
 127       * @param \phpseclib3\Math\BigInteger $n
 128       * @param \phpseclib3\Math\BigInteger $e
 129       * @param array $options optional
 130       * @return string
 131       */
 132      public static function savePublicKey(BigInteger $n, BigInteger $e, array $options = [])
 133      {
 134          $key = [
 135              'kty' => 'RSA',
 136              'n' => Strings::base64url_encode($n->toBytes()),
 137              'e' => Strings::base64url_encode($e->toBytes())
 138          ];
 139  
 140          return self::wrapKey($key, $options);
 141      }
 142  }