Commit f2d21125 authored by Sjoerd Langkemper's avatar Sjoerd Langkemper
Browse files

use classes, use only one algorithm at a time

parent 72b95475
No related merge requests found
Showing with 65 additions and 150 deletions
+65 -150
<?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']);
}
}
<?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)]);
}
}
......@@ -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>
......
......@@ -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
......
<?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');
hs256.php 0 → 100644
<?php
require_once 'MishalHS256.php';
$jwtImpl = new MishalHS256();
include 'base.php';
<?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');
rs256.php 0 → 100644
<?php
require_once 'FirebaseRS256.php';
$jwtImpl = new FirebaseRS256();
include 'base.php';
<?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');
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment