# 简介

Json web token (JWT), 是为了在网络应用环境间传递声明而执行的一种基于 JSON 的开放标准((RFC 7519). 该 token 被设计为紧凑且安全的,特别适用于分布式站点的单点登录(SSO)场景。JWT 的声明一般被用来在身份提供者和服务提供者间传递被认证的用户身份信息,以便于从资源服务器获取资源,也可以增加一些额外的其它业务逻辑所必须的声明信息,该 token 也可直接被用于认证,也可被加密。

# 构成

分为三个部分,分别为头部(Header)、声明(Claims,也可以称为负载 Payload)、证书(Signature),三个部分以英文句号 . 隔开。其中 header 是声明的类型和加密使用的算法。下面是一个用 HS256 生成 JWT 的代码例子: HMACSHA256(base64UrlEncode(header) + "." +base64UrlEncode(payload),secret)

头部(Header):

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

alg:是说明这个 JWT 的签名使用的算法的参数,常见值用 HS256(默认),HS512 等,也可以为 None。HS256 表示 HMAC SHA256。
typ:说明这个 token 的类型为 JWT

声明(Claims):

{
  "exp": 1416471934,
  "user_name": "user",
  "scope": [
    "read",
    "write"
  ],
  "authorities": [
    "ROLE_ADMIN",
    "ROLE_USER"
  ],
  "jti": "9bc92a44-0b1a-4c5e-be70-da52075b9a84",
  "client_id": "my-client-with-secret"
}

JWT 固定参数有:
iss:发行人
exp:到期时间
sub:主题
aud:用户
nbf:在此之前不可用
iat:发布时间
jti:JWT ID 用于标识该 JWT

签名(Signature):
服务器有一个不会发送给客户端的密码(secret),用头部中指定的算法对头部和声明的内容用此密码进行加密,生成的字符串就是 JWT 的签名。

# 安全问题

# Header 部分

  • 是否支持修改算法为 none / 对称加密算法
  • 删除签名
  • 插入错误信息
  • 直接在 header 中加入新的公钥
  • kid 字段是否有 SQL 注入 / 命令注入 / 目录遍历
  • 结合业务功能通过 kid 直接下载对应公私钥
  • 是否强制使用白名单上的加密算法
  • JWKS 劫持
  • JKU (JWK Set URL) / X5U (X.509 URL) 注入

# Payload 部分

  • 其中是否存在敏感信息
  • 检查过期策略,比如 exp , iat

# Signature 部分

  • 检查是否强制检查签名
  • 密钥是否可以爆破
  • 是否可以通过其他方式拿到密钥

# 其他

  • 重放
  • 通过匹配校验的时间做时间攻击
  • 修改算法 RS256 为 HS256
  • 弱密钥破解

# 参考链接

  • Critical vulnerabilities in JSON Web Token libraries
  • JWT CODE