繁体   English   中英

验证 JWT 令牌签名,无需在 PyJWT 库中对其进行解码

[英]Verify the JWT token signature without decoding it in the PyJWT library

是否可以验证 JWT 令牌签名而不在 PyJWT 库中对其进行解码?

我不知道我是否得到你的要求,但无论如何我都会尝试。

整个 JWT 标准在此链接中得到了很好的解释。 本质上,如果我理解您的要求,您希望在不解码令牌本身的情况下检查签名。 为了回答您的问题,我将使用链接中的一些内容。

在其紧凑形式中,JSON Web 令牌由由点 (.) 分隔的三个部分组成,它们是:

  • Header:通常由两部分组成,令牌的类型,即 JWT,以及正在使用的签名算法,例如 HMAC SHA256 或 RSA(您使用的是 RSA)。

  • 有效载荷:包含声明。 声明是关于实体的陈述(这是您正在解码以找到我假设的公钥的链接)

  • 签名:要创建签名部分,您必须获取编码的 header、编码的有效负载、秘密、header 中指定的算法,并对其进行签名。 例如,如果您想使用 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 仅提供解码方法,它需要一个完整的令牌(标题+有效负载+签名),就像示例中一样。 此外,您必须存储在第一次读取令牌期间获得的 header 以获取使用的加密算法(如果更改)。

但是,你为什么不想再次解码呢? 这样,您甚至可以检查它是否与已签名的消息相同,并且没有人篡改消息。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM