27 if (is_string($source)) {
28 $source = json_decode($source,
true);
29 }
else if (is_object($source)) {
30 if (property_exists($source,
'keys'))
31 $source = (array)$source;
36 if (is_array($source)) {
37 if (isset($source[
'keys']))
38 $source = $source[
'keys'];
40 foreach ($source as $k => $v) {
42 if (is_array($v) && isset($v[
'kid']))
44 elseif (is_object($v) && property_exists($v,
'kid'))
50 }
catch (UnexpectedValueException $e) {
55 if (0 < count($keys)) {
58 throw new UnexpectedValueException(
'Failed to parse JWK');
68 if (!is_array($source))
69 $source = (array)$source;
70 if (!empty($source) && isset($source[
'kty']) && isset($source[
'n']) && isset($source[
'e'])) {
71 switch ($source[
'kty']) {
73 if (array_key_exists(
'd', $source))
74 throw new UnexpectedValueException(
'Failed to parse JWK: RSA private key is not supported');
76 $pem = self::createPemFromModulusAndExponent($source[
'n'], $source[
'e']);
77 $pKey = openssl_pkey_get_public($pem);
87 throw new UnexpectedValueException(
'Failed to parse JWK');
98 private static function createPemFromModulusAndExponent($n, $e)
105 'modulus' => pack(
'Ca*a*', 2, self::encodeLength(strlen($modulus)), $modulus),
106 'publicExponent' => pack(
'Ca*a*', 2, self::encodeLength(strlen($publicExponent)), $publicExponent)
109 $RSAPublicKey = pack(
112 self::encodeLength(strlen($components[
'modulus']) + strlen($components[
'publicExponent'])),
113 $components[
'modulus'],
114 $components[
'publicExponent']
119 $rsaOID = pack(
'H*',
'300d06092a864886f70d0101010500');
120 $RSAPublicKey = chr(0) . $RSAPublicKey;
121 $RSAPublicKey = chr(3) . self::encodeLength(strlen($RSAPublicKey)) . $RSAPublicKey;
123 $RSAPublicKey = pack(
126 self::encodeLength(strlen($rsaOID . $RSAPublicKey)),
127 $rsaOID . $RSAPublicKey
130 $RSAPublicKey =
"-----BEGIN PUBLIC KEY-----\r\n" .
131 chunk_split(base64_encode($RSAPublicKey), 64) .
132 '-----END PUBLIC KEY-----';
134 return $RSAPublicKey;
147 private static function encodeLength($length)
149 if ($length <= 0x7F) {
153 $temp = ltrim(pack(
'N', $length), chr(0));
154 return pack(
'Ca*', 0x80 | strlen($temp), $temp);
static parseKeySet($source)
static urlsafeB64Decode($input)