是否可以验证 JWT 令牌签名而不在 PyJWT 库中对其进行解码?
1 回答
我不知道我是否得到了您的要求,但无论如何我都会尝试。
这个链接很好地解释了整个 JWT 标准。本质上,如果我理解您的要求,您希望在不解码令牌本身的情况下检查签名。为了回答您的问题,我将使用链接中的一些内容。
在其紧凑的形式中,JSON Web Token 由以点 (.) 分隔的三部分组成,它们是:
标头:通常由两部分组成,令牌的类型,即 JWT,以及正在使用的签名算法,例如 HMAC SHA256 或 RSA(您正在使用 RSA)。
有效载荷:包含声明。声明是关于实体的陈述(这是您正在解码以找到我假设的公钥的链接)
签名:要创建签名部分,您必须获取编码的标头、编码的有效负载、秘密、标头中指定的算法,并对其进行签名。例如,如果您想使用 HMAC SHA256 算法,签名将通过以下方式创建:
HMACSHA256(base64UrlEncode(标题)+“。”+ base64UrlEncode(有效负载),秘密)
签名用于验证消息在此过程中没有被更改,并且在使用私钥签名的令牌的情况下,它还可以验证 JWT 的发送者就是它所说的那个人。
这三个元素都是base64编码的,用“.”连接。因此 JWT 是这样的:akuhsdk.wqkhkwje.sajgdhwqj
因此,如果我想签署一条消息以证明它来自我,我可以使用我自己的私钥生成一个签名。任何有兴趣验证消息的人都可以使用我的公钥来确认签名是否有效。
此时,接收者可以通过解密签名并检查它是否有效来验证签名(大多数密码库都会抛出错误)。如果不是,那么用于加密它的私钥不是密钥对中的那个。
示例:
import jwt
token = 'eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiJ9.eyJ1c2VyX2lkIjoxMjN9.HT1kBSdGFAznrhbs2hB6xjVDilMUmKA-_36n1pLLtFTKHoO1qmRkUcy9bJJwGuyfJ_dbzBMyBwpXMj-EXnKQQmKlXsiItxzLVIfC5qE97V6l6S0LzT9bzixvgolwi-qB9STp0bR_7suiXaON-EzBWFh0PzZi7l5Tg8iS_0_iSCQQlX5MSJW_-bHESTf3dfj5GGbsRBRsi1TRBzvxMUB6GhNsy6rdUhwoTkihk7pljISTYs6BtNoGRW9gVUzfA2es3zwBaynyyMeSocYet6WJri97p0eRnVGtHSWwAmnzZ-CX5-scO9uYmb1fT1EkhhjGhnMejee-kQkMktCTNlPsaUAJyayzdgEvQeo5M9ZrfjEnDjF7ntI03dck1t9Bgy-tV1LKH0FWNLq3dCJJrYdQx--A-I7zW1th0C4wNcDe_d_GaYopbtU-HPRG3Z1SPKFuX1m0uYhk9aySvkec66NBfvV2xEgo8lRZyNxntXkMdeJCEiLF1UhQvvSvmWaWC-0uRulYACn4H-tZiaK7zvpcPkrsfJ7iR_O1bxMPziKpsM4b7c7tmsEcOUZY-IHEI9ibd54_A1O72i08sCWKT5CXyG70MAPqyR0MFlcV7IuDtBW3LCqyvfsDVk4eIj8VcSU1OKQJ1Gl-CTOHEyN-ncV3NslVLaT9Q1C4E7uK2QpS8z0'
public_key = 'ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAACAQCcjWidoIPNRc3IN1hoGeOdSvDkBDK3W3P7/4HxLf62nvUQVczL3FG+dG9KSRnzuvRoUi1o3TASO3Yn72FSfaLPE/JmOtpu/IGuB/oF/CrJqEHA/08n0xkNQK8kwdIqayKPS84PVOm8XomNijMpUCahqu9cGZDPhlgqD8PAxw4e1ZQSizWj0hTSCR78dmHAEr5oXryP6uD0Mw/KGKYel/KTMu00dShWPzHnJeLaYvKgMJKPN6pqhsWFQsNUDnKd9tgn3NSPeHECnnBbUxB2BeuVz72+HnyFWah3mpGH4Dr+9rjRXiPg2AYxgR3U93AEQ6osefxeIKUSCXWx1txNV07QzwFVag4vPBmrA9XktC7i5EP91wxUOsyzhG8geXKuDHmE+/7U3AsExHYFkBLqMnW92CaTeQ408xsRXjxWjSNHpfqhZVxGY5Eh8L3NVqgRg1LdnZYHpovi1iP4Zx2Z7Nb5F9ejuMsA+v/D0WL3c6bhwU8BKdD7YZDG2tpzq6PHt+NarGkcWWh9/p/SIJoZi+e35mjcUMfnRD8w/ouL0sTnxebT7xBCVucfRoMPA67USoChDpc+pNsdtsqlQOZMgpPZYfjIyCThv5mwjEKHnytBq46ULOFlHt0opplDANnDsvWwqEobhACZM+n2ZNtu36eoc3bC/Hak8ACEi5DixirF0w== miguel@MS90J8G8WL'
payload = jwt.decode(token, public_key, algorithms=['RS256'])
print(payload)
所以,是的,你可以做到。
但是要完成您对代码的要求,您必须使用其他一些库(加密),因为 pyJWT 仅提供解码方法,它需要一个完整的令牌(标题+有效负载+签名),就像示例中一样。此外,您必须存储在第一次读取令牌期间获得的标头以获取使用的加密算法(如果更改)。
但是,你为什么不想再次解码呢?这样,您甚至可以检查它是否与已签名的消息相同,并且没有人篡改消息。