我应该能够在 HS256 编码的 JWT 中看到模式吗?

信息安全 加密 jwt 令牌
2021-08-29 00:00:00

我正在使用此标头摆弄https://jwt.io/

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

当我意识到用重复的东西替换有效负载名称时AAAAAAAAAAAAAAAAAAAA会产生这样的令牌:

eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkFBQUFBQUFBQUFBQUFBQUFBQUFBIiwiaWF0IjoxNTE2MjM5MDIyfQ.hlXlWvaeyOb6OcrOwd-xfWgF8QlfmTycj5WWZwRr6FY

您可以看到BQUF子字符串似乎是重复的。A我在名称中添加的 s 越多,显示的BQUFs 就越多。

据我所知,这些模式的存在使得查找编码内容变得相当容易。我错过了什么?

3个回答

tl/dr:您选择的 JWT 版本不加密任何内容,它只是对其进行编码以便于传输。有效载荷中的数据并不意味着保密。

您有一个 JWS(带签名的 JWT)。您正在查看的只是 base64 编码的数据有效负载。JWS 包含3 个部分

  1. base64 编码的标头
  2. base64 编码数据
  3. 加密签名

Base64 只是一种编码格式 - 不是任何类型的加密,也不意味着隐藏数据。相反,它只是确保它仅由标准 ASCII 字符组成,这些字符很容易在不同系统之间传输。因此,如果您将这两个时期之间的所有内容都获取并通过 base64 解码器运行,您将毫无问题地看到原始有效负载数据。

因此,键很简单:JWS并不意味着隐藏数据。它只是意图(通过签名)来确保数据完整性,即如果有人更改数据有效载荷,那么您将知道,因为您的签名将不再匹配。

或者,您可以使用 JWE(带加密的 JWT)来隐藏您的数据。有关JWT、JWS 和 JWE 之间更详细的比较,请参阅Bob 的优秀答案,所有这些都密切相关。

这里的术语有点混乱。

JWT定义了声明的基本格式,以及一些标准声明。它指定 JWT 声明集应该是 JWS 的有效负载或 JWE 结构。

JWS为某些带有签名的有效负载定义了一个结构。虽然实际上负载几乎总是 JWT,但这不是规范的要求。最常见的形式是 JWS Compact Serialization,它是Header.Payload.Signature您熟悉的 Base64 格式。请注意,不涉及加密,仅涉及签名。这可以1保证令牌是由受信任方创建且未被修改(真实性),但不会隐藏其内容。

JWE是 JWS 的加密对应物。与 JWS 非常相似,它通常包含 JWT 有效负载(作为其明文),但这不是必需的。JWE 紧凑序列化与 JWS 等效项有些不同:Header.Key.IV.Ciphertext.AuthenticationTag. 这应该1具有与 JWS 相同的安全保证(真实性)2,并添加了对没有密钥的任何人隐藏消息(机密性)。


您所拥有的特别是一个 JWS,它已签名但未加密(如HS256算法中所示,它代表“使用SHA-256的HMAC ”)。如果需要加密,则应改为使用JWA定义的加密算法之一创建 JWE 。


进一步阅读:


1与始终一样,任何“保证”取决于正确配置的所有内容。并且,您不是例如使用调试配置,使其成为未加密/无符号的所有内容。

2假设经过身份验证的加密。

您缺少的是您的令牌已签名(或更准确地说,使用对称密钥进行了身份验证)但未加密。

如果您在上面的问题中使用令牌,在句点 ( ) 处将其分成三部分.并将每一部分输入base64 解码器,您将获得以下解码输出:

{"alg":"HS256","typ":"JWT"}
{"sub":"1234567890","name":"AAAAAAAAAAAAAAAAAAAA","iat":1516239022}

以及 32 个主要是非 ASCII 字节的序列,这是令牌其余部分的 256 位 HMAC 身份验证标记。如您所见,任何人都可以轻松读取所有数据。身份验证标签仅防止不知道 HMAC 密钥的任何人修改令牌或从头开始创建伪造的令牌。