15
15
*/
16
16
class JWT
17
17
{
18
- public static $ only_method = 'HS256 ' ;
19
-
20
- public static $ methods = array (
18
+ public static $ supported_algs = array (
21
19
'HS256 ' => array ('hash_hmac ' , 'SHA256 ' ),
22
20
'HS512 ' => array ('hash_hmac ' , 'SHA512 ' ),
23
21
'HS384 ' => array ('hash_hmac ' , 'SHA384 ' ),
@@ -27,9 +25,9 @@ class JWT
27
25
/**
28
26
* Decodes a JWT string into a PHP object.
29
27
*
30
- * @param string $jwt The JWT
31
- * @param string|Array|null $key The secret key, or map of keys
32
- * @param bool $verify Don't skip verification process
28
+ * @param string $jwt The JWT
29
+ * @param string|Array|null $key The secret key, or map of keys
30
+ * @param bool $algs List of supported verification algorithms
33
31
*
34
32
* @return object The JWT's payload as a PHP object
35
33
*
@@ -43,7 +41,7 @@ class JWT
43
41
* @uses jsonDecode
44
42
* @uses urlsafeB64Decode
45
43
*/
46
- public static function decode ($ jwt , $ key = null , $ verify = true )
44
+ public static function decode ($ jwt , $ key = null , $ algs = array () )
47
45
{
48
46
$ tks = explode ('. ' , $ jwt );
49
47
if (count ($ tks ) != 3 ) {
@@ -57,10 +55,13 @@ public static function decode($jwt, $key = null, $verify = true)
57
55
throw new UnexpectedValueException ('Invalid claims encoding ' );
58
56
}
59
57
$ sig = JWT ::urlsafeB64Decode ($ cryptob64 );
60
- if ($ verify ) {
58
+ if (! empty ( $ key ) ) {
61
59
if (empty ($ header ->alg )) {
62
60
throw new DomainException ('Empty algorithm ' );
63
61
}
62
+ if (empty (self ::$ supported_algs [$ header ->alg ])) {
63
+ throw new DomainException ('Algorithm not supported ' );
64
+ }
64
65
if (is_array ($ key )) {
65
66
if (isset ($ header ->kid )) {
66
67
$ key = $ key [$ header ->kid ];
@@ -105,16 +106,16 @@ public static function decode($jwt, $key = null, $verify = true)
105
106
*
106
107
* @param object|array $payload PHP object or array
107
108
* @param string $key The secret key
108
- * @param string $algo The signing algorithm. Supported
109
+ * @param string $alg The signing algorithm. Supported
109
110
* algorithms are 'HS256', 'HS384' and 'HS512'
110
111
*
111
112
* @return string A signed JWT
112
113
* @uses jsonEncode
113
114
* @uses urlsafeB64Encode
114
115
*/
115
- public static function encode ($ payload , $ key , $ algo = 'HS256 ' , $ keyId = null )
116
+ public static function encode ($ payload , $ key , $ alg = 'HS256 ' , $ keyId = null )
116
117
{
117
- $ header = array ('typ ' => 'JWT ' , 'alg ' => $ algo );
118
+ $ header = array ('typ ' => 'JWT ' , 'alg ' => $ alg );
118
119
if ($ keyId !== null ) {
119
120
$ header ['kid ' ] = $ keyId ;
120
121
}
@@ -123,7 +124,7 @@ public static function encode($payload, $key, $algo = 'HS256', $keyId = null)
123
124
$ segments [] = JWT ::urlsafeB64Encode (JWT ::jsonEncode ($ payload ));
124
125
$ signing_input = implode ('. ' , $ segments );
125
126
126
- $ signature = JWT ::sign ($ signing_input , $ key , $ algo );
127
+ $ signature = JWT ::sign ($ signing_input , $ key , $ alg );
127
128
$ segments [] = JWT ::urlsafeB64Encode ($ signature );
128
129
129
130
return implode ('. ' , $ segments );
@@ -134,24 +135,24 @@ public static function encode($payload, $key, $algo = 'HS256', $keyId = null)
134
135
*
135
136
* @param string $msg The message to sign
136
137
* @param string|resource $key The secret key
137
- * @param string $method The signing algorithm. Supported algorithms
138
+ * @param string $alg The signing algorithm. Supported algorithms
138
139
* are 'HS256', 'HS384', 'HS512' and 'RS256'
139
140
*
140
141
* @return string An encrypted message
141
142
* @throws DomainException Unsupported algorithm was specified
142
143
*/
143
- public static function sign ($ msg , $ key , $ method = 'HS256 ' )
144
+ public static function sign ($ msg , $ key , $ alg = 'HS256 ' )
144
145
{
145
- if (empty (self ::$ methods [ $ method ])) {
146
+ if (empty (self ::$ supported_algs [ $ alg ])) {
146
147
throw new DomainException ('Algorithm not supported ' );
147
148
}
148
- list ($ function , $ algo ) = self ::$ methods [ $ method ];
149
+ list ($ function , $ algorithm ) = self ::$ supported_algs [ $ alg ];
149
150
switch ($ function ) {
150
151
case 'hash_hmac ' :
151
- return hash_hmac ($ algo , $ msg , $ key , true );
152
+ return hash_hmac ($ algorithm , $ msg , $ key , true );
152
153
case 'openssl ' :
153
154
$ signature = '' ;
154
- $ success = openssl_sign ($ msg , $ signature , $ key , $ algo );
155
+ $ success = openssl_sign ($ msg , $ signature , $ key , $ algorithm );
155
156
if (!$ success ) {
156
157
throw new DomainException ("OpenSSL unable to sign data " );
157
158
} else {
@@ -166,32 +167,28 @@ public static function sign($msg, $key, $method = 'HS256')
166
167
* @param string $msg the original message
167
168
* @param string $signature
168
169
* @param string|resource $key for HS*, a string key works. for RS*, must be a resource of an openssl public key
169
- * @param string $method
170
+ * @param string $algorithms
170
171
* @return bool
171
172
* @throws DomainException Invalid Algorithm or OpenSSL failure
172
173
*/
173
- public static function verify ($ msg , $ signature , $ key , $ method = ' HS256 ' )
174
+ private static function verify ($ msg , $ signature , $ key , $ alg )
174
175
{
175
- if (empty (self ::$ methods [ $ method ])) {
176
+ if (empty (self ::$ supported_algs [ $ alg ])) {
176
177
throw new DomainException ('Algorithm not supported ' );
177
178
}
178
- if (self ::$ only_method === null ) {
179
- throw new DomainException ('Algorithm not specified ' );
180
- } elseif ($ method !== self ::$ only_method ) {
181
- throw new DomainException ('Incorrect algorithm error ' );
182
- }
183
- list ($ function , $ algo ) = self ::$ methods [$ method ];
179
+
180
+ list ($ function , $ algorithm ) = self ::$ supported_algs [$ alg ];
184
181
switch ($ function ) {
185
182
case 'openssl ' :
186
- $ success = openssl_verify ($ msg , $ signature , $ key , $ algo );
183
+ $ success = openssl_verify ($ msg , $ signature , $ key , $ algorithm );
187
184
if (!$ success ) {
188
185
throw new DomainException ("OpenSSL unable to verify data: " . openssl_error_string ());
189
186
} else {
190
187
return $ signature ;
191
188
}
192
189
case 'hash_hmac ' :
193
190
default :
194
- $ hash = hash_hmac ($ algo , $ msg , $ key , true );
191
+ $ hash = hash_hmac ($ algorithm , $ msg , $ key , true );
195
192
if (function_exists ('hash_equals ' )) {
196
193
return hash_equals ($ signature , $ hash );
197
194
}
@@ -309,7 +306,7 @@ private static function handleJsonError($errno)
309
306
: 'Unknown JSON error: ' . $ errno
310
307
);
311
308
}
312
-
309
+
313
310
/**
314
311
* Get the number of bytes in cryptographic strings.
315
312
*
@@ -323,22 +320,4 @@ private static function safeStrlen($str)
323
320
}
324
321
return strlen ($ str );
325
322
}
326
-
327
- /**
328
- * Set the only allowed method for this server.
329
- *
330
- * @ref https://auth0.com/blog/2015/03/31/critical-vulnerabilities-in-json-web-token-libraries/
331
- *
332
- * @param string $method array index in self::$methods
333
- *
334
- * @return boolean
335
- */
336
- public static function setOnlyAllowedMethod ($ method )
337
- {
338
- if (!empty (self ::$ methods [$ method ])) {
339
- self ::$ only_method = $ method ;
340
- return true ;
341
- }
342
- return false ;
343
- }
344
323
}
0 commit comments