【发布时间】:2021-04-17 14:43:37
【问题描述】:
我正在使用 PHP 解析从外部 API 返回的 JWT 令牌。 解析有效负载很容易,但我想首先检查令牌中使用的密钥是否与我服务器上的密钥匹配。这将作为我的握手。为此,我将使用我认为已使用的密钥重新创建令牌的签名部分(第三部分)。如果结果值匹配,那么我知道密钥匹配。
例如,我的密钥是:testsecretkey
返回给我的Token是:
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1bmlxdWVfbmFtZSI6IjIzMTc2MiIsIklkIjoiMTM0IiwiSWRQZXJzb24iOiIxMTkiLCJQZXJzb25lblJvbGxlbiI6Ilt7XCJSb2xsZVwiOjEsXCJJZFwiOjE0MTg5fSx7XCJSb2xsZVwiOjIsXCJJZFwiOjExOX0se1wiUm9sbGVcIjozLFwiSWRcIjoxMDY5MH1dIiwibmJmIjoxNjEwNDYxNjA2LCJleHAiOjE2MTA0NjUyMDYsImlhdCI6MTYxMDQ2MTYwNn0.Cqz2mtZ9g_L4BSYTQztzQ4W0VldAf-Ihok24jVVi8iE P>
如果我通过https://jwt.io/ 运行它并在“验证签名”框中输入“testscretkey”并单击“秘密 base64 编码”复选框,一切都会检查出来,并且令牌看起来是正确的。
回到我在 PHP 中的服务器上,我使用 "." 将令牌分成 3 部分 ($tokenParts)作为分隔符。编码签名(第 3 部分,上面令牌的最后一部分)显示...:
Cqz2mtZ9g_L4BSYTQztzQ4W0VldAf-Ihok24jVVi8iE
我将我的密钥加密应用于令牌部分 1 和 2:
$base64UrlSignature = base64_encode(
hash_hmac(
'sha256', //The correct enc type
$tokenParts[0] . "." . $tokenParts[1], //The first 2 parts of the token
'testsecretkey', // The secret key that should have been used
true
)
);
...然后我将我的新签名 ($base64UrlSignature) 与原始编码签名 ($tokenParts[2]) 进行比较。如果两者都匹配,则确认握手。
但是,即使我使用了相同的键,值也不匹配。相反,我的新签名是:
K4Mx71y1yRdQ7xotyR78FzQU8J2xTc65wZbhGFE-s4s
如果我取消选中“秘密 base64 编码”复选框,则返回 jwt.io(原始令牌信息仍输入框中)我可以看到 JWT 令牌签名(蓝色)更改为与我相同的值新签名($base64UrlSignature)。但这对我来说毫无意义,因为我已经对我的新签名进行了 base64_encoded。
谁能帮我找出我哪里出错了?
谢谢
【问题讨论】: