深入理解 Json Web Token(JWT):结构、应用与安全漏洞

简介

  • 介绍: 全名Json Web Token, 遵循JSON格式,将用户信息加密到token里,服务器不保存任何用户信息,只保存密钥信息,通过使用特定加密算法验证token,通过token验证用户身份
  • 结构: 由 标头(Header)、有效载荷(Payload)和签名(Signature) 三个段落 组成 (签名可没有)
    每个段落用英文句号连接, 且每个段落单独用base64url加密 : 即使alg为none, 即没有签名, 结尾也需要点号
  • Header: 作用: 一般由两个字段组成, 即algtyp, 也有可选此字段kidalg: 指定token加密使用的算法(最常用的为HMAC和RSA算法 -- HS256 RS256 ES256 none) typ: 指定令牌的类型, 值基本为JWTkid: 指定使用的加密算法的密钥 在服务端的位置
  • Payload: 作用: 储存着用户数据以及一些元数据有关的声明,声明有三种(注册声明 公共声明 私有声明) 注册声明: 由JWT系统自身预定义的声明
    • iss (Issuer): 令牌的发行者
    • sub (Subject): 令牌的主题
    • aud (Audience): 令牌的接收者
    • exp (Expiration Time): 过期时间
    • nbf (Not Before): 在此之前不可用
    • iat (Issued At): 发行时间
    • jti (JWT ID): 唯一标识符 公共声明: 由使用JWT的人自由定义, 用于传递 非敏感信息 私有声明: 由使用JWT的人自由定义, 用于传递 敏感信息
  • Signature: 作用: 用于保护token完整性, 验证消息在传输过程中没有被更改, : 并且对于使用私钥签名的token,它还可以验证JWT的发送方 生成方法: 将header和payload两部分base64urlEncode后联结起来, 再用header指定的算法, 计算出签名 即如HMAC-SHA256(base64urlEncode(header) + '.' + base64urlEncode(payload), secret_key)
  • 服务端: 储存: 验证签名的密钥 (对于对称加密,这是一个密钥;对于非对称加密,这是一个私钥和公钥对) : JWT本身并不提供相关任何信息的存储, 而交给服务端自己进行逻辑操作与存储
  • 使用:

    1. 服务端根据登陆状态 将用户信息加密到token中,返给客户端
    2. 客户端收到服务端返回的token, 存储在cookie中, 并且每次通信都带上token. 服务端解密toke, 验证内容,完成相应逻辑
    • JWT的最佳用途是一次性授权Token, 用于给用户的操作进行标识, 而非给用户的状态进行标识
  • 与session的区别: 内容: session会话返回的cookie只用于标识, 本身并没有任何含义; 而JWT包含了用户的相关信息 管理方法: JWT理论上应用于无状态的请求; 而Session由于主要信息储存在客户端, 可用于有状态的请求 跨平台: JWT比较容易跨平台; 而Session基本不能跨平台(得相关平台服务器会话数据互通才可)

--通用漏洞--

未对签名进行验证

  • 前提: 服务端未对签名进行验证
  • 原理: 服务端可能没有对token签名进行校验, 此时, 攻击者便可任意修改Payload和Header中的值

未对加密算法进行强验证 -- 空加密

  • 前提: 生产环境中开启空加密算法, 且不检验alg
  • 使用: 只需在header中指定alg为none, 然后把signature设置为空(但点号仍旧要在), 服务器不会验证签名

修改加密算法(RSA改为HMAC)

  • 前提: 知道RSA公钥, 服务端不验证alg字段
  • 原理: HMAC是对称加密算法, 而RSA为非对称算法, 因为加密时的 私钥 基本无法获取, 而进行验证的 公钥 可通过某些方式获取, 所以将RSA改为HMAC加密, 用获得的公钥伪造HMAC签名, 服务端会用公钥进行验证
  • 使用: 获得RSA加密公钥后, alg中改为HS256, 用公钥伪造HS256签名, 传输

爆破密钥

  • 前提: 使用对称加密
  • 爆破工具: [[hashcat]] [[jwtcrack]] (hashcat为字典爆破, jwtcrack为暴力爆破,密钥长度五位以上则耗时非常长)
  • 爆破后: 爆破后使用对应密钥伪造签名(密钥要进行base64url加密后伪造)
./jwtcrack <token> [alphabet] [max_len] [hmac_alg]
hashcat -a 0 -m 16500 <token> <wordlist>

修改KID参数

  • 原理: kid用于读取密钥文件, 若修改该字段的值, 可能造成相关的 文件读取漏洞
  • 任意文件读取: 将kid值修改为对应文件的路径, 可读取任意文件 (如 /etc/passwd)
暂无评论

发送评论 编辑评论


				
|´・ω・)ノ
ヾ(≧∇≦*)ゝ
(☆ω☆)
(╯‵□′)╯︵┴─┴
 ̄﹃ ̄
(/ω\)
∠( ᐛ 」∠)_
(๑•̀ㅁ•́ฅ)
→_→
୧(๑•̀⌄•́๑)૭
٩(ˊᗜˋ*)و
(ノ°ο°)ノ
(´இ皿இ`)
⌇●﹏●⌇
(ฅ´ω`ฅ)
(╯°A°)╯︵○○○
φ( ̄∇ ̄o)
ヾ(´・ ・`。)ノ"
( ง ᵒ̌皿ᵒ̌)ง⁼³₌₃
(ó﹏ò。)
Σ(っ °Д °;)っ
( ,,´・ω・)ノ"(´っω・`。)
╮(╯▽╰)╭
o(*////▽////*)q
>﹏<
( ๑´•ω•) "(ㆆᴗㆆ)
😂
😀
😅
😊
🙂
🙃
😌
😍
😘
😜
😝
😏
😒
🙄
😳
😡
😔
😫
😱
😭
💩
👻
🙌
🖕
👍
👫
👬
👭
🌚
🌝
🙈
💊
😶
🙏
🍦
🍉
😣
Source: github.com/k4yt3x/flowerhd
颜文字
Emoji
小恐龙
花!
上一篇
下一篇