问题描述
所以我为同一个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=='
现在,除了最后两个字符“ ==”和此“ /”之外,它们是相同的。有人可以向我解释为什么会这样吗?仅仅是base64的填充,实际上是否有两个相等的符号并不重要?这就是为什么jwt.io删除它们吗?
编辑: 将编码的python代码更改为jps的提示就可以了:
import hmac
import hashlib
import base64
s= b"eyJhbGciOiJIUzUxMiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ"
res = base64.b64encode(hmac.new(b"abc",digestmod=hashlib.sha512).digest())
x = res.decode("utf-8")
x = x.replace("+","-")
x = x.replace("/","_")
x = x.replace("=","")
print(x)
解决方法
在Python代码中,您使用了Base64编码,但是JWT standard需要Base64URL编码。区别在于Base64编码中的字符“ +”和“ /”被替换为“-”和“ _”,并且省略了填充。
根据接收方Base64URL解码器的实现,它可能会或可能不会工作。为了安全起见,我建议您遵循标准。