API: fix JWT signature verification

Fixes https://github.com/shaarli/Shaarli/issues/737

Added:
- Base64Url utilities

Fixed:
- use URL-safe Base64 encoding/decoding functions
- use byte representations for HMAC digests
- all JWT parts are Base64Url-encoded

See:
- https://en.wikipedia.org/wiki/JSON_Web_Token
- https://tools.ietf.org/html/rfc7519
- https://scotch.io/tutorials/the-anatomy-of-a-json-web-token
- https://jwt.io/introduction/
- https://en.wikipedia.org/wiki/Base64#URL_applications
- https://secure.php.net/manual/en/function.base64-encode.php#103849

Signed-off-by: VirtualTam <virtualtam@flibidi.net>
This commit is contained in:
VirtualTam 2017-01-04 11:41:05 +01:00
parent fc11ab2f29
commit 7a9daac56d
4 changed files with 49 additions and 13 deletions

View file

@ -2,6 +2,9 @@
namespace Shaarli\Api;
use Shaarli\Base64Url;
/**
* Class ApiUtilsTest
*/
@ -24,14 +27,14 @@ class ApiUtilsTest extends \PHPUnit_Framework_TestCase
*/
public static function generateValidJwtToken($secret)
{
$header = base64_encode('{
$header = Base64Url::encode('{
"typ": "JWT",
"alg": "HS512"
}');
$payload = base64_encode('{
$payload = Base64Url::encode('{
"iat": '. time() .'
}');
$signature = hash_hmac('sha512', $header .'.'. $payload , $secret);
$signature = Base64Url::encode(hash_hmac('sha512', $header .'.'. $payload , $secret, true));
return $header .'.'. $payload .'.'. $signature;
}
@ -46,9 +49,9 @@ class ApiUtilsTest extends \PHPUnit_Framework_TestCase
*/
public static function generateCustomJwtToken($header, $payload, $secret)
{
$header = base64_encode($header);
$payload = base64_encode($payload);
$signature = hash_hmac('sha512', $header . '.' . $payload, $secret);
$header = Base64Url::encode($header);
$payload = Base64Url::encode($payload);
$signature = Base64Url::encode(hash_hmac('sha512', $header . '.' . $payload, $secret, true));
return $header . '.' . $payload . '.' . $signature;
}