Bitrix-D7 23.9
 
Загрузка...
Поиск...
Не найдено
jwk.php
1<?php
2namespace Bitrix\Main\Web;
3
4use UnexpectedValueException;
5
17class JWK
18{
24 public static function parseKeySet($source)
25 {
26 $keys = [];
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;
32 else
33 $source = [$source];
34 }
35
36 if (is_array($source)) {
37 if (isset($source['keys']))
38 $source = $source['keys'];
39
40 foreach ($source as $k => $v) {
41 if (!is_string($k)) {
42 if (is_array($v) && isset($v['kid']))
43 $k = $v['kid'];
44 elseif (is_object($v) && property_exists($v, 'kid'))
45 $k = $v->{'kid'};
46 }
47 try {
48 $v = self::parseKey($v);
49 $keys[$k] = $v;
50 } catch (UnexpectedValueException $e) {
51 //Do nothing
52 }
53 }
54 }
55 if (0 < count($keys)) {
56 return $keys;
57 }
58 throw new UnexpectedValueException('Failed to parse JWK');
59 }
60
66 public static function parseKey($source)
67 {
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']) {
72 case 'RSA':
73 if (array_key_exists('d', $source))
74 throw new UnexpectedValueException('Failed to parse JWK: RSA private key is not supported');
75
76 $pem = self::createPemFromModulusAndExponent($source['n'], $source['e']);
77 $pKey = openssl_pkey_get_public($pem);
78 if ($pKey !== false)
79 return $pKey;
80 break;
81 default:
82 //Currently only RSA is supported
83 break;
84 }
85 }
86
87 throw new UnexpectedValueException('Failed to parse JWK');
88 }
89
98 private static function createPemFromModulusAndExponent($n, $e)
99 {
100 $modulus = JWT::urlsafeB64Decode($n);
101 $publicExponent = JWT::urlsafeB64Decode($e);
102
103
104 $components = array(
105 'modulus' => pack('Ca*a*', 2, self::encodeLength(strlen($modulus)), $modulus),
106 'publicExponent' => pack('Ca*a*', 2, self::encodeLength(strlen($publicExponent)), $publicExponent)
107 );
108
109 $RSAPublicKey = pack(
110 'Ca*a*a*',
111 48,
112 self::encodeLength(strlen($components['modulus']) + strlen($components['publicExponent'])),
113 $components['modulus'],
114 $components['publicExponent']
115 );
116
117
118 // sequence(oid(1.2.840.113549.1.1.1), null)) = rsaEncryption.
119 $rsaOID = pack('H*', '300d06092a864886f70d0101010500'); // hex version of MA0GCSqGSIb3DQEBAQUA
120 $RSAPublicKey = chr(0) . $RSAPublicKey;
121 $RSAPublicKey = chr(3) . self::encodeLength(strlen($RSAPublicKey)) . $RSAPublicKey;
122
123 $RSAPublicKey = pack(
124 'Ca*a*',
125 48,
126 self::encodeLength(strlen($rsaOID . $RSAPublicKey)),
127 $rsaOID . $RSAPublicKey
128 );
129
130 $RSAPublicKey = "-----BEGIN PUBLIC KEY-----\r\n" .
131 chunk_split(base64_encode($RSAPublicKey), 64) .
132 '-----END PUBLIC KEY-----';
133
134 return $RSAPublicKey;
135 }
136
147 private static function encodeLength($length)
148 {
149 if ($length <= 0x7F) {
150 return chr($length);
151 }
152
153 $temp = ltrim(pack('N', $length), chr(0));
154 return pack('Ca*', 0x80 | strlen($temp), $temp);
155 }
156
157}
static parseKey($source)
Definition jwk.php:66
static parseKeySet($source)
Definition jwk.php:24
static urlsafeB64Decode($input)
Definition jwt.php:328