diff --git a/FirebaseRS256.php b/FirebaseRS256.php new file mode 100644 index 0000000000000000000000000000000000000000..dfb292ffcd64db955536c1754777a1eb3b2c95a8 --- /dev/null +++ b/FirebaseRS256.php @@ -0,0 +1,21 @@ +<?php +require __DIR__ . '/vendor/autoload.php'; + +use \Firebase\JWT\JWT; + +class FirebaseRS256 { + function __construct() { + $this->private_key = file_get_contents('private.pem'); + $this->public_key = file_get_contents('public.pem'); + } + + function encodeJwt($tokenObj) { + return JWT::encode($tokenObj, $this->private_key, 'RS256'); + } + + function decodeJwt($token) { + // Explicitly configured to be vulnerable: + // we expect a RS256 signature, but also accept a HS256 signature. + return JWT::decode($token, $this->public_key, ['RS256', 'HS256']); + } +} diff --git a/MishalHS256.php b/MishalHS256.php new file mode 100644 index 0000000000000000000000000000000000000000..e4f10336f20896ec92ac2673956be26efab4e6f7 --- /dev/null +++ b/MishalHS256.php @@ -0,0 +1,23 @@ +<?php +require __DIR__ . '/vendor/autoload.php'; + +use Jwt\Jwt; +use Jwt\Algorithm\NoneAlgorithm; +use Jwt\Algorithm\HS256Algorithm; + +class MishalHS256 { + function __construct() { + $this->algorithms = [ + 'none' => new NoneAlgorithm(), + 'HS256' => new HS256Algorithm('secret'), + ]; + } + + function encodeJwt($tokenObj) { + return Jwt::encode($tokenObj, $this->algorithms['HS256']); + } + + function decodeJwt($token) { + return JWT::decode($token, ['algorithm' => array_values($this->algorithms)]); + } +} diff --git a/base.php b/base.php index 832db13984d9ae5b50ab3c72ac021096f89b7107..bf919b2833d8aa9d5ec953c9fd01f58cf608463c 100644 --- a/base.php +++ b/base.php @@ -3,20 +3,23 @@ <xmp> <?php +require_once __DIR__ . '/common.php'; + +if (!isset($jwtImpl)) { + die(); +} + $token = getToken(); -$algorithms = getAlgorithmKeys(); if ($token) { try { - printValidJwt(decodeJwt($token)); + printValidJwt($jwtImpl->decodeJwt($token)); } catch (Exception $e) { printInvalidJwt($e); } } else { - foreach ($algorithms as $name => $keys) { - $jwt = encodeJwt(createTokenObject(), $name, $keys); - echo "$name: $jwt\n"; - } + $jwt = $jwtImpl->encodeJwt(createTokenObject()); + echo "JWT: $jwt\n"; } ?> </xmp> diff --git a/common.php b/common.php index a882e61cd744f57f48508f0b5fb05d45843030d5..7996accb9906d7857c2b897c4476e6a566f20b7d 100644 --- a/common.php +++ b/common.php @@ -9,23 +9,6 @@ function getToken() { return $auth_header; } -function getAlgorithmKeys() { - $shared_key = "secret"; - $private_key = file_get_contents('private.pem'); - $public_key = file_get_contents('public.pem'); - - return [ - 'none' => '', - 'HS256' => $shared_key, - 'RS256' => [$private_key, $public_key], - ]; -} - -function getAlgorithm($jwt) { - $header = json_decode(base64_decode(substr($auth_header, 0, strpos($auth_header, '.')))); - return $header->alg; -} - function createTokenObject() { return array( # Issuer diff --git a/firebasejwt.php b/firebasejwt.php deleted file mode 100644 index 43e55f5af1c08cfa24cfa3d1955cae4d9c91a1ee..0000000000000000000000000000000000000000 --- a/firebasejwt.php +++ /dev/null @@ -1,28 +0,0 @@ -<?php -require __DIR__ . '/vendor/autoload.php'; -require_once __DIR__ . '/common.php'; - -use \Firebase\JWT\JWT; - -JWT::$leeway = 10; // $leeway in seconds - -function encodeJwt($tokenObj, $algorithmName, $keys) { - if ($algorithmName == 'none') { - return "not supported"; - } - - $key = $keys; - if (is_array($keys)) { - $key = $keys[0]; - } - return JWT::encode($tokenObj, $key, $algorithmName); -} - -function decodeJwt($token) { - $keys = getAlgorithmKeys(); - $key = $keys['RS256'][1]; - - return JWT::decode($token, $key, array_keys($keys)); -} - -include('base.php'); diff --git a/hs256.php b/hs256.php new file mode 100644 index 0000000000000000000000000000000000000000..a15d53361c24c0f100ee867fe9d1f7d6f70f7098 --- /dev/null +++ b/hs256.php @@ -0,0 +1,6 @@ +<?php + +require_once 'MishalHS256.php'; + +$jwtImpl = new MishalHS256(); +include 'base.php'; diff --git a/mishaljwt.php b/mishaljwt.php deleted file mode 100644 index 2295ef655eeaf2dae1e6ba8c8fac37a4e8d33d5b..0000000000000000000000000000000000000000 --- a/mishaljwt.php +++ /dev/null @@ -1,31 +0,0 @@ -<?php -require __DIR__ . '/vendor/autoload.php'; -require __DIR__ . '/common.php'; - -use Jwt\Jwt; -use Jwt\Algorithm\NoneAlgorithm; -use Jwt\Algorithm\HS256Algorithm; -use Jwt\Algorithm\RS256Algorithm; - -function getAlgorithmObjects() { - $keys = getAlgorithmKeys(); - - $algorithms = [ - 'none' => new NoneAlgorithm(), - 'HS256' => new HS256Algorithm($keys['HS256']), - 'RS256' => new RS256Algorithm($keys['RS256'][0], $keys['RS256'][1]), - ]; - return $algorithms; -} - -function decodeJwt($token) { - $algorithms = getAlgorithmObjects(); - return JWT::decode($token, ['algorithm' => array_values($algorithms)]); -} - -function encodeJwt($tokenObj, $algorithmName, $keys) { - $algorithms = getAlgorithmObjects(); - return Jwt::encode($tokenObj, $algorithms[$algorithmName]); -} - -include('base.php'); diff --git a/rs256.php b/rs256.php new file mode 100644 index 0000000000000000000000000000000000000000..cc76d8fbe8fc05c87b80041aab999c1d7cc4cc35 --- /dev/null +++ b/rs256.php @@ -0,0 +1,6 @@ +<?php + +require_once 'FirebaseRS256.php'; + +$jwtImpl = new FirebaseRS256(); +include 'base.php'; diff --git a/sjordjwt.php b/sjordjwt.php deleted file mode 100644 index e8fff00a670535b6e471582b76d39c12006a3493..0000000000000000000000000000000000000000 --- a/sjordjwt.php +++ /dev/null @@ -1,68 +0,0 @@ -<?php - -require __DIR__ . '/common.php'; - -function urlsafeB64Encode($input) -{ - return str_replace('=', '', strtr(base64_encode($input), '+/', '-_')); -} - -function urlsafeB64Decode($input) -{ - $remainder = strlen($input) % 4; - if ($remainder) { - $padlen = 4 - $remainder; - $input .= str_repeat('=', $padlen); - } - return base64_decode(strtr($input, '-_', '+/')); -} - - -function verifySignature($signature, $message, $algo, $key) { - if ($algo == 'HS256') { - return $signature == hash_hmac('SHA256', $message, $key, true); - } else if ($algo == 'RS256') { - return openssl_verify($message, $signature, $key, 'SHA256'); - } else if ($algo == 'none') { - return $signature == ''; - } else { - throw new Exception("Unsupported algorithm $algo"); - } -} - -function decodeJwt($token) { - list($header, $content, $signature) = explode('.', $token); - $headerObj = json_decode(urlsafeB64Decode($header)); - $contentObj = json_decode(urlsafeB64Decode($content)); - - $key = file_get_contents('public.pem'); - if (!verifySignature(urlsafeB64Decode($signature), "$header.$content", $headerObj->alg, $key)) { - throw new Exception("Invalid signature"); - } - - return $contentObj; -} - -function createSignature($message, $algo, $keys) { - if ($algo == 'HS256') { - return hash_hmac('SHA256', $message, $keys, true); - } else if ($algo == 'RS256') { - $signature = ''; - openssl_sign($message, $signature, $keys[0], 'SHA256'); - return $signature; - } else if ($algo == 'none') { - return ''; - } else { - throw new Exception("Unsupported algorithm $algo"); - } -} - -function encodeJwt($tokenObj, $algorithmName, $keys) { - $headerObj = ["alg" => $algorithmName, "typ" => "JWT"]; - $header = urlsafeB64Encode(json_encode($headerObj)); - $content = urlsafeB64Encode(json_encode($tokenObj)); - $signature = urlsafeB64Encode(createSignature("$header.$content", $algorithmName, $keys)); - return "$header.$content.$signature"; -} - -include('base.php');