JWT 签名和验证签名的过程
生成(签名)JWT
确定 Header:Header 通常包含两部分信息:使用的算法(比如 HS256 表示 HMAC SHA-256)和 Token 类型(通常是 JWT)。
{
"alg": "HS256",
"typ": "JWT"
}
构建 Payload:Payload 包含 claims,这些 claims 可以是注册的 claims、公共的 claims 或私有的 claims
{
"sub": "1234567890",
"name": "John Doe",
"iat": 1516239022
}
签名:使用 Header 中指定的算法和一个密钥对 Header 和 Payload 进行签名。签名的目的是验证 Token 在传输过程中未被篡改。
例如,如果使用 HMAC SHA-256,签名过程将是
HMACSHA256(
base64UrlEncode(header) + "." +
base64UrlEncode(payload),
secret)
组合 JWT:将编码后的 Header、Payload 和签名组合成一个 JWT。格式通常为header.payload.signature
。
JWT 验证过程
分解 JWT:首先,从 JWT 字符串中分离出 Base64 编码的 Header、Payload 和 Signature。JWT 通常形如header.payload.signature
。
Base64 解码:将编码的 Header 和 Payload 解码回它们原始的 JSON 格式的字符串。
重新生成签名:使用相同的算法(Header 中指定的,如 HMAC SHA-256)和secret
对解码后的 Header 和 Payload 重新生成签名。具体步骤如下:
- 将解码后的 Header 和 Payload 重新转换成 Base64 编码的字符串。
- 将这两个 Base64 字符串用点
.
连接起来形成一个新的字符串。 - 使用
secret
作为密钥,对这个字符串进行 HMAC SHA-256 运算,生成新的签名。
比较签名:将重新生成的签名与 JWT 中原来包含的签名进行比较。如果两者相同,则认为 JWT 是有效的,没有被篡改,且是由掌握secret
的实体发行的。
Secret 的作用
在这个验证过程中,secret
起到的是保证签名真实性和数据未被篡改的关键角色:
- 签名的安全性:只有知道
secret
的实体才能正确生成和验证签名。这意味着即使有人截获了 JWT,但没有secret
,他们也无法生成新的有效签名,从而无法伪造有效的 JWT。 - 数据的完整性:通过比较重新生成的签名和 JWT 中的签名,可以确认数据在传输过程中未被修改。因为任何对 Header 或 Payload 的改动都会导致新生成的签名与原签名不匹配。
检查 Claims:验证签名之后,还需要检查 Payload 中的 claims,如exp
(过期时间)来确定 Token 的有效性。
注意
虽然 JWT 的 Header 和 Payload 是使用 Base64 编码的,这种编码是可逆的,因此任何人都可以看到内容。如果需要保密 Payload 中的数据,应考虑对 Payload 进行加密,这种情况下通常使用 JWE(JSON Web Encryption)。