Custom JWT IN PHP 一直说无效签名
Custom JWT IN PHP keeps saying Invalid signature
我是新手,我正在尽力创建自己的 JWT class。我想我做的一切都是对的,但是当我尝试将我的令牌粘贴到 jwt.io 时,它一直说签名无效。我忍不住觉得我要么错过了一些愚蠢的东西,要么出了什么问题。
我的代码如下:
class Jwt
{
protected $header;
protected $payload;
protected $signature;
protected $secret;
protected $alg;
protected $jwt;
function __construct($header, $payload, $secret)
{
$this->SetHeader($header);
$this->alg = $header['alg'];
$this->SetPayload($payload);
$this->secret = $secret;
$this->SetSignature();
}
public function SetHeader($header){
$this->header = str_replace(["+", "/", "="],
['-', '_',""],
base64_encode(json_encode($header)));
}
public function SetPayload($payload)
{
$this->payload =
str_replace(["+", "/", "="],
['-', '_',""],
base64_encode(json_encode($payload)));
}
public function SetSignature()
{
$data = $this->header.".".$this->payload;
$this->alg = str_replace('HS', 'sha', $this->alg);
$hashedData = hash_hmac($this->alg, $data , $this->secret, true);
$this->signature = str_replace(
["+", "/", "="], ['-', '_', ""], base64_encode($hashedData)
);
}
public function SetJwt()
{
$this->jwt = $this->header.'.'.$this->payload.'.'.$this->signature;
}
public function GetJwt()
{
return $this->jwt;
}
在我的 Index.php:
use root\lib\Jwt;
$myFavorites =
['element' => 'Sun', 'animal' => 'Leopard','color'=>'Orange'];
$secret = bin2hex(random_bytes(32));
$jwt = new Jwt
(['alg' => 'HS256', 'typ' => 'JWT'], $myFavorites, $secret)
$jwt->SetJwt();
var_dump($jwt->GetJwt());
一切正常,调试器显示正确的输出,但不知何故它只是说签名无效。
如果我在 jwt.io 网站上更改算法,它会起作用。所以我猜它与签名或算法有关
我正在从 var_dump 屏幕上的输出中复制它,这可能是原因吗?
新令牌是:eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9。eyJlbGVtZW50IjoiU3VuIiwiYW5pbWFsIjoiTGVvcGFyZCIsImNvbG91ciI6Im9yYW5nZSJ9.LF-4HNxgzhqYaIQKTImwO8A8SHIZfVYz2iG57A4tQm0
我什至尝试在第 header 个 HS256 或 HS384 中更改算法,然后在函数内对更改进行硬编码,这没有区别
如有任何建议,我们将不胜感激
在您的代码中,您使用的是采用算法参数 sha256
或 sha384
的 HMAC 散列。这些算法名称与可在 JWT 中使用的算法名称不同。
在RFC 7517 section 4.1.1
你可以阅读 alg
header:
A list of defined "alg" values for this use can be found in the IANA
"JSON Web Signature and Encryption Algorithms" registry established
by [JWA]; the initial contents of this registry are the values
defined in Section 3.1 of [JWA].
根据 RFC7518 section 3.1 对于 HMAC ShaXXX 算法,您使用 HSXXX
,例如 HS256
或 HS384
JWT.io 调试器或任何其他试图验证 JWT 的软件读取此 header 然后尝试使用算法。如果您使用非标准名称,验证软件将无法找到正确的算法。
关于使用 JWT.io 的注意事项:不要忘记将密码粘贴到调试器右栏 Verify Signature
下的输入字段中,之前 您将令牌粘贴到左栏中。如果忘记密码,则无法验证令牌,如果将密码粘贴在令牌后,签名可能会重新计算并在左侧更改。
我是新手,我正在尽力创建自己的 JWT class。我想我做的一切都是对的,但是当我尝试将我的令牌粘贴到 jwt.io 时,它一直说签名无效。我忍不住觉得我要么错过了一些愚蠢的东西,要么出了什么问题。
我的代码如下:
class Jwt
{
protected $header;
protected $payload;
protected $signature;
protected $secret;
protected $alg;
protected $jwt;
function __construct($header, $payload, $secret)
{
$this->SetHeader($header);
$this->alg = $header['alg'];
$this->SetPayload($payload);
$this->secret = $secret;
$this->SetSignature();
}
public function SetHeader($header){
$this->header = str_replace(["+", "/", "="],
['-', '_',""],
base64_encode(json_encode($header)));
}
public function SetPayload($payload)
{
$this->payload =
str_replace(["+", "/", "="],
['-', '_',""],
base64_encode(json_encode($payload)));
}
public function SetSignature()
{
$data = $this->header.".".$this->payload;
$this->alg = str_replace('HS', 'sha', $this->alg);
$hashedData = hash_hmac($this->alg, $data , $this->secret, true);
$this->signature = str_replace(
["+", "/", "="], ['-', '_', ""], base64_encode($hashedData)
);
}
public function SetJwt()
{
$this->jwt = $this->header.'.'.$this->payload.'.'.$this->signature;
}
public function GetJwt()
{
return $this->jwt;
}
在我的 Index.php:
use root\lib\Jwt;
$myFavorites =
['element' => 'Sun', 'animal' => 'Leopard','color'=>'Orange'];
$secret = bin2hex(random_bytes(32));
$jwt = new Jwt
(['alg' => 'HS256', 'typ' => 'JWT'], $myFavorites, $secret)
$jwt->SetJwt();
var_dump($jwt->GetJwt());
一切正常,调试器显示正确的输出,但不知何故它只是说签名无效。
如果我在 jwt.io 网站上更改算法,它会起作用。所以我猜它与签名或算法有关
我正在从 var_dump 屏幕上的输出中复制它,这可能是原因吗?
新令牌是:eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9。eyJlbGVtZW50IjoiU3VuIiwiYW5pbWFsIjoiTGVvcGFyZCIsImNvbG91ciI6Im9yYW5nZSJ9.LF-4HNxgzhqYaIQKTImwO8A8SHIZfVYz2iG57A4tQm0
我什至尝试在第 header 个 HS256 或 HS384 中更改算法,然后在函数内对更改进行硬编码,这没有区别
如有任何建议,我们将不胜感激
在您的代码中,您使用的是采用算法参数 sha256
或 sha384
的 HMAC 散列。这些算法名称与可在 JWT 中使用的算法名称不同。
在RFC 7517 section 4.1.1
你可以阅读 alg
header:
A list of defined "alg" values for this use can be found in the IANA "JSON Web Signature and Encryption Algorithms" registry established by [JWA]; the initial contents of this registry are the values defined in Section 3.1 of [JWA].
根据 RFC7518 section 3.1 对于 HMAC ShaXXX 算法,您使用 HSXXX
,例如 HS256
或 HS384
JWT.io 调试器或任何其他试图验证 JWT 的软件读取此 header 然后尝试使用算法。如果您使用非标准名称,验证软件将无法找到正确的算法。
关于使用 JWT.io 的注意事项:不要忘记将密码粘贴到调试器右栏 Verify Signature
下的输入字段中,之前 您将令牌粘贴到左栏中。如果忘记密码,则无法验证令牌,如果将密码粘贴在令牌后,签名可能会重新计算并在左侧更改。