JWT,如何验证签名



我有这个JWT:

eyJhbGciOiJSUzI1NiIsImtpZCI6IjVkMzQwZGRiYzNjNWJhY2M0Y2VlMWZiOWQxNmU5ODM3ZWM2MTYzZWIiLCJ0eXAiOiJKV1QifQ.eyJuYW1lIjoiemFnYWxvIiwiaXNzIjoiaHR0cHM6Ly9zZWN1cmV0b2tlbi5nb29nbGUuY29tL3Byb2ZlcHQtM2M0NzkiLCJhdWQiOiJwcm9mZXB0LTNjNDc5IiwiYXV0aF90aW1lIjoxNjY2MjkxNDAzLCJ1c2VyX2lkIjoiZ1JtdnFYb0tySE85T0RLUURCYTBWNnRaNTBLMiIsInN1YiI6ImdSbXZxWG9LckhPOU9ES1FEQmEwVjZ0WjUwSzIiLCJpYXQiOjE2NjYyOTE0MDMsImV4cCI6MTY2NjI5NTAwMywiZW1haWwiOiJyc2p1bGlhb0BnbWFpbC5jb20iLCJlbWFpbF92ZXJpZmllZCI6ZmFsc2UsImZpcmViYXNlIjp7ImlkZW50aXRpZXMiOnsiZW1haWwiOlsicnNqdWxpYW9AZ21haWwuY29tIl19LCJzaWduX2luX3Byb3ZpZGVyIjoicGFzc3dvcmQifX0.ZkBqE8GCSGt9FX_LxoaLNgHcPx19EDMq3ARmZaJ_R1_FiBcQAp8T_AEmleVu68lqw7SdcM2aAjZ1kZbfkZ48hgfhW0LI03VC_6Dc4sq9pgCHWarteCeUz4fE1B6nl4nIbKI3nPQorKYTu82SXEzaRiEwHQCVayiMmnkjzj4d-2YVp4WA8If_h3jNHBe8giskjwkB2t6hB39vYLqvcM5sEeSBRpVT8zA-hmp2AeImcXagCK4Av7JIt_iBNuwT9dwMLtA6addoXcDYTJuRZ3GhVrbL8x_is9u2XDDLWDWdrj1yAjkq7pTPwC7KPft8Md2PKxqYR5bid_VRSjPIeb_k8A

这个公钥

-----BEGIN PUBLIC KEY-----
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA3CTs4UeO1cS3FJAWDTcO
HHcAeEfZOCFmxju1xC+kSAw9RVQTykKzgNAREUQyGFvp1WwC51r1QHMwNyk+wsDG
/h4mbDIgECMeEEGh2qnHgFIVWJ12H5oP/WHVvho/GgVuOkJzCuHTTVYGSaKi43IR
VZqO7784VfzHsHl/caUqv/pOu8MjsynD8QVzac0XrdXHTqYUMWm0rFCrEm+UWFHK
KQK2skzQxFTUTcI2NtG+TjNFiHGs3ZzAfd+N6PuW3FpX3TsNN0fWmFbqgUH0oduV
9Qd2XhZ2TtnAK4+FVCLJDuqk8XkAe9Ibmgelz+aKtwFGN1bx8TilswsvepGjDpMj
AwIDAQAB
-----END PUBLIC KEY-----

使用网站https://jwt.io/,可以运行签名验证,一切正常!

现在,为了更好地了解正在发生的事情,我想亲自签名

我的第一步是使用这个头json:作为输入生成头

{"alg":"RS256","kid":"5d340ddbc3c5bacc4cee1fb9d16e9837ec6163eb","typ":"JWT"}

只需使用base64UrlEncode翻译即可获得:

eyJhbGciOiJSUzI1NiIsImtpZCI6IjVkMzQwZGRiYzNjNWJhY2M0Y2VlMWZiOWQxNmU5ODM3ZWM2MTYzZWIiLCJ0eXAiOiJKV1QifQ

对表示有效负载的json进行相同的转换,我们得到了正确的结果!

{"name":"zagalo","iss":"https://securetoken.google.com/profept-3c479","aud":"profept-3c479","auth_time":1666291403,"user_id":"gRmvqXoKrHO9ODKQDBa0V6tZ50K2","sub":"gRmvqXoKrHO9ODKQDBa0V6tZ50K2","iat":1666291403,"exp":1666295003,"email":"rsjuliao@gmail.com","email_verified":false,"firebase":{"identities":{"email":["rsjuliao@gmail.com"]},"sign_in_provider":"password"}}

eyJuYW1lIjoiemFnYWxvIiwiaXNzIjoiaHR0cHM6Ly9zZWN1cmV0b2tlbi5nb29nbGUuY29tL3Byb2ZlcHQtM2M0NzkiLCJhdWQiOiJwcm9mZXB0LTNjNDc5IiwiYXV0aF90aW1lIjoxNjY2MjkxNDAzLCJ1c2VyX2lkIjoiZ1JtdnFYb0tySE85T0RLUURCYTBWNnRaNTBLMiIsInN1YiI6ImdSbXZxWG9LckhPOU9ES1FEQmEwVjZ0WjUwSzIiLCJpYXQiOjE2NjYyOTE0MDMsImV4cCI6MTY2NjI5NTAwMywiZW1haWwiOiJyc2p1bGlhb0BnbWFpbC5jb20iLCJlbWFpbF92ZXJpZmllZCI6ZmFsc2UsImZpcmViYXNlIjp7ImlkZW50aXRpZXMiOnsiZW1haWwiOlsicnNqdWxpYW9AZ21haWwuY29tIl19LCJzaWduX2luX3Byb3ZpZGVyIjoicGFzc3dvcmQifX0

最后一部分:

根据jwt.io,签名为:

RSASHA256(
base64UrlEncode(header) + "." +
base64UrlEncode(payload))

让我们假设:
H=base64UrlEncode(标头(

p=base64UrlEncode(有效负载(
因此,SIGNATURE=RSASHA256(H+'.'+p(

如何获得签名?我一直在尝试各种策略来产生正确的结果,但我没有成功。

我该怎么做才能得到正确的结果?我的主要策略是获得SHA256的结果,并用上面的公钥将其作为RSA的参数,但结果不一样。我做错了什么?我需要学些什么来解决我缺乏knologe的问题?

当您只有RSA的公钥时,无法生成消息的签名。您需要私钥来生成签名。使用";RS256";JWT的算法是";RSASSA-PKCS1-v1_5使用SHA-256";,如RFC 7518-3.3中所定义的。RSASSA-PKCS1-v1_5:数字签名

+-------------------+---------------------------------+
| "alg" Param Value | Digital Signature Algorithm     |
+-------------------+---------------------------------+
| RS256             | RSASSA-PKCS1-v1_5 using SHA-256 |
| RS384             | RSASSA-PKCS1-v1_5 using SHA-384 |
| RS512             | RSASSA-PKCS1-v1_5 using SHA-512 |
+-------------------+---------------------------------+

数字签名算法";RSASSA-PKS1-v1_ 5";其本身在RFC 3447-8.2中进行了定义。RSASSA-PKCS1-v1_5。实际签名算法在RFC 3447-8.2.1签名生成操作中定义:

RSASSA-PKCS1-V1_5-SIGN (K, M)
Input:
K        signer's RSA private key
M        message to be signed, an octet string
Output:
S        signature, an octet string of length k, where k is the
length in octets of the RSA modulus n

如您所见,您需要;签名者的RSA私钥";K生成消息M的签名(这将是您的JWT头和有效载荷(。

您只能使用公钥来验证给定签名是否有效,而不能创建新签名。只有私钥的所有者才能做到这一点。

最新更新