[ Index ] |
PHP Cross Reference of DokuWiki |
[Summary view] [Print] [Text view]
1 <?php 2 3 /** 4 * JSON Web Key (RFC7517 / RFC8037) Formatted EC 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\EC\Formats\Keys; 15 16 use phpseclib3\Common\Functions\Strings; 17 use phpseclib3\Crypt\Common\Formats\Keys\JWK as Progenitor; 18 use phpseclib3\Crypt\EC\BaseCurves\Base as BaseCurve; 19 use phpseclib3\Crypt\EC\BaseCurves\TwistedEdwards as TwistedEdwardsCurve; 20 use phpseclib3\Crypt\EC\Curves\Ed25519; 21 use phpseclib3\Crypt\EC\Curves\secp256k1; 22 use phpseclib3\Crypt\EC\Curves\secp256r1; 23 use phpseclib3\Crypt\EC\Curves\secp384r1; 24 use phpseclib3\Crypt\EC\Curves\secp521r1; 25 use phpseclib3\Exception\UnsupportedCurveException; 26 use phpseclib3\Math\BigInteger; 27 28 /** 29 * JWK Formatted EC Handler 30 * 31 * @author Jim Wigginton <terrafrost@php.net> 32 */ 33 abstract class JWK extends Progenitor 34 { 35 use Common; 36 37 /** 38 * Break a public or private key down into its constituent components 39 * 40 * @param string $key 41 * @param string $password optional 42 * @return array 43 */ 44 public static function load($key, $password = '') 45 { 46 $key = parent::load($key, $password); 47 48 switch ($key->kty) { 49 case 'EC': 50 switch ($key->crv) { 51 case 'P-256': 52 case 'P-384': 53 case 'P-521': 54 case 'secp256k1': 55 break; 56 default: 57 throw new UnsupportedCurveException('Only P-256, P-384, P-521 and secp256k1 curves are accepted (' . $key->crv . ' provided)'); 58 } 59 break; 60 case 'OKP': 61 switch ($key->crv) { 62 case 'Ed25519': 63 case 'Ed448': 64 break; 65 default: 66 throw new UnsupportedCurveException('Only Ed25519 and Ed448 curves are accepted (' . $key->crv . ' provided)'); 67 } 68 break; 69 default: 70 throw new \Exception('Only EC and OKP JWK keys are supported'); 71 } 72 73 $curve = '\phpseclib3\Crypt\EC\Curves\\' . str_replace('P-', 'nistp', $key->crv); 74 $curve = new $curve(); 75 76 if ($curve instanceof TwistedEdwardsCurve) { 77 $QA = self::extractPoint(Strings::base64url_decode($key->x), $curve); 78 if (!isset($key->d)) { 79 return compact('curve', 'QA'); 80 } 81 $arr = $curve->extractSecret(Strings::base64url_decode($key->d)); 82 return compact('curve', 'QA') + $arr; 83 } 84 85 $QA = [ 86 $curve->convertInteger(new BigInteger(Strings::base64url_decode($key->x), 256)), 87 $curve->convertInteger(new BigInteger(Strings::base64url_decode($key->y), 256)) 88 ]; 89 90 if (!$curve->verifyPoint($QA)) { 91 throw new \RuntimeException('Unable to verify that point exists on curve'); 92 } 93 94 if (!isset($key->d)) { 95 return compact('curve', 'QA'); 96 } 97 98 $dA = new BigInteger(Strings::base64url_decode($key->d), 256); 99 100 $curve->rangeCheck($dA); 101 102 return compact('curve', 'dA', 'QA'); 103 } 104 105 /** 106 * Returns the alias that corresponds to a curve 107 * 108 * @return string 109 */ 110 private static function getAlias(BaseCurve $curve) 111 { 112 switch (true) { 113 case $curve instanceof secp256r1: 114 return 'P-256'; 115 case $curve instanceof secp384r1: 116 return 'P-384'; 117 case $curve instanceof secp521r1: 118 return 'P-521'; 119 case $curve instanceof secp256k1: 120 return 'secp256k1'; 121 } 122 123 $reflect = new \ReflectionClass($curve); 124 $curveName = $reflect->isFinal() ? 125 $reflect->getParentClass()->getShortName() : 126 $reflect->getShortName(); 127 throw new UnsupportedCurveException("$curveName is not a supported curve"); 128 } 129 130 /** 131 * Return the array superstructure for an EC public key 132 * 133 * @param \phpseclib3\Crypt\EC\BaseCurves\Base $curve 134 * @param \phpseclib3\Math\Common\FiniteField\Integer[] $publicKey 135 * @return array 136 */ 137 private static function savePublicKeyHelper(BaseCurve $curve, array $publicKey) 138 { 139 if ($curve instanceof TwistedEdwardsCurve) { 140 return [ 141 'kty' => 'OKP', 142 'crv' => $curve instanceof Ed25519 ? 'Ed25519' : 'Ed448', 143 'x' => Strings::base64url_encode($curve->encodePoint($publicKey)) 144 ]; 145 } 146 147 return [ 148 'kty' => 'EC', 149 'crv' => self::getAlias($curve), 150 'x' => Strings::base64url_encode($publicKey[0]->toBytes()), 151 'y' => Strings::base64url_encode($publicKey[1]->toBytes()) 152 ]; 153 } 154 155 /** 156 * Convert an EC public key to the appropriate format 157 * 158 * @param \phpseclib3\Crypt\EC\BaseCurves\Base $curve 159 * @param \phpseclib3\Math\Common\FiniteField\Integer[] $publicKey 160 * @param array $options optional 161 * @return string 162 */ 163 public static function savePublicKey(BaseCurve $curve, array $publicKey, array $options = []) 164 { 165 $key = self::savePublicKeyHelper($curve, $publicKey); 166 167 return self::wrapKey($key, $options); 168 } 169 170 /** 171 * Convert a private key to the appropriate format. 172 * 173 * @param \phpseclib3\Math\BigInteger $privateKey 174 * @param \phpseclib3\Crypt\EC\Curves\Ed25519 $curve 175 * @param \phpseclib3\Math\Common\FiniteField\Integer[] $publicKey 176 * @param string $secret optional 177 * @param string $password optional 178 * @param array $options optional 179 * @return string 180 */ 181 public static function savePrivateKey(BigInteger $privateKey, BaseCurve $curve, array $publicKey, $secret = null, $password = '', array $options = []) 182 { 183 $key = self::savePublicKeyHelper($curve, $publicKey); 184 $key['d'] = $curve instanceof TwistedEdwardsCurve ? $secret : $privateKey->toBytes(); 185 $key['d'] = Strings::base64url_encode($key['d']); 186 187 return self::wrapKey($key, $options); 188 } 189 }
title
Description
Body
title
Description
Body
title
Description
Body
title
Body