JWT hs512签名与JWT.io略有不同,如果使用python计算



所以我为同一JWT获得了不同的签名。

标题

{
"alg": "HS512",
"typ": "JWT"
}

有效载荷

{
"sub": "1234567890",
"name": "John Doe",
"iat": 1516239022
}

作为签名密钥abc";

JWT.io生成的JWT如下:eyJhbGciOiJIUzUxMiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.sNgS2IRq0LCvUaIzg9dCBVvmY_9KnrXDEmKTii6U4APbRMeUkU084wf3h5v4baP2WeZOyGunCTEa9wxh25IW6w

如果我用python这样计算签名:

import hmac
import hashlib
import base64
s= b"eyJhbGciOiJIUzUxMiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ"
res = base64.b64encode(hmac.new(b"abc", msg=s, digestmod=hashlib.sha512).digest())
print(res)

则打印:b'sNgS2IRq0LCvUaIzg9dCBVvmY/9KnrXDEmKTii6U4APbRMeUkU084wf3h5v4baP2WeZOyGunCTEa9wxh25IW6w=='

现在除了最后两个字符"=="而这个"/"它们是相同的。有人能向我解释为什么会这样吗?这只是底座64的填充物吗?实际上,两个等号是否存在并不重要?这就是jwt.io删除它们的原因吗?

编辑:根据jps的提示更改python代码可以做到这一点:

import hmac
import hashlib
import base64
s= b"eyJhbGciOiJIUzUxMiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ"
res = base64.b64encode(hmac.new(b"abc", msg=s, digestmod=hashlib.sha512).digest())
x = res.decode("utf-8")
x = x.replace("+","-")
x = x.replace("/","_")
x = x.replace("=", "")
print(x)

在Python代码中,您使用了Base64编码,但JWT标准需要Base64URL编码。不同之处在于,字符"+"以及"/"在Base64编码中-"以及"_"并且省略了该填充。

它可能工作,也可能不工作,这取决于接收端Base64URL解码器的实现。为了安全起见,我建议遵循这个标准。

相关内容

最新更新