提交需求
*
*

*
*
*
立即提交
点击”立即提交”,表明我理解并同意 《美创科技隐私条款》

logo

    产品与服务
    解决方案
    技术支持
    合作发展
    关于美创

    申请试用
      JWT(JSON Web Token)安全解析
      发布时间:2021-08-06 阅读次数: 198 次

      在当今的互联网服务中,存在用户交互的地方通常都会有用户认证。一般来说,用户认证流程会有以下几步:


      1.用户输入用户名密码,发送到服务端;


      2.服务端校验通过后,会将用户登录信息保存在当前会话中(session);


      3.服务端返回一个会话id(session id)到用户端,这个session id通常会保存在cookie中;


      4.之后用户每次发起请求时都会带上这个session id;


      5.服务端校验session id来判断用户请求的身份是否合法。


      这种session+cookie的模式,是互联网应用中最为流行的用户认证模式。但是这种模式在当下单点登录、统一认证、跨域等场景下用户体验并不是很好,认证成本也较高;同时,由于seesion id保存在cookie中,这种用户认证模式也更容易受到XSS、CSRF等漏洞的影响。


      01JWT概述


      在JWT官网的定义中,JSON Web Token (JWT) 是一个开放标准 ( RFC 7519 ),定义了一种紧凑且自包含的方式,用于在各方之间使用 JSON 对象安全地传输信息。该信息可以被验证和信任,因为它是经过数字签名的。JWT 使用密钥进行签名。


      简单来说,JWT遵循JSON格式,将用户信息加密保存在一个JSON格式的token中,服务端不保存任何与用户认证的相关配置信息,只保存校验token签名的密钥,通过签名的校验来判断用户身份是否合法。基于token的身份验证可以替代传统的cookie+session身份验证方法。



      02JWT结构


      访问https://jwt.io/,可以清晰的看到JWT的数据结构及其组成部分。


      example:


      eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c




      左边的是在实际的用户认证中所使用的JWT数据,它是一个较长的加密字符串,被两个“.”符号分成三段。这三段内容分别对应右边的组成JWT的三个部分:HEADER、PAYLOAD、SIGNATURE。


      HEADER部分是一个JSON对象:


      {


      "alg":"HS256",


      "typ":"JWT"


      }


      HEADER部分的数据是描述JWT的元数据,alg属性代表的是加密签名的算法,通常为HMAC算法或者RSA算法;typ属性代表token的类型,默认为JWT。


      PAYLOAD部分也是一个JSON对象,包含官方定义的属性(一共7个,可自行查询了解)和自定义的属性:


      {


      "sub":"1234567890",


      "name":"John Doe",


      "iat":1516239022


      }


      PAYLOAD部分的数据是实际的用户身份数据,如用户名、用户id、生效时间、过期时间等,这部分的数据属性可以使用官方的7个属性,也可自行扩展定义。


      SIGNATURE部分的数据是对HEADER和PAYLOAD两部分数据的签名,可以确保token不被篡改,SIGNATURE的生成需要依靠密钥、算法以及生成公式。


      03JWT攻击手法


      在针对JWT的攻击手法中,常用的主要有以下3种:


      1.空加密算法攻击:将alg设置为None,告诉服务器不进行签名校验,从而使伪造的token可以绕过签名检验而被服务端认定为合法身份。


      以上面的数据为例


      下载github上的开源脚本


      https://github.com/Ch1ngg/JWTPyCrack


      使用该脚本生成PAYLOAD为


      {


      "sub":"1234567890",


      "name":"John Doe",


      "iat":1516239022


      }


      alg为None的JWT


      pythonjwtcrack.py -m generate -s{"sub":"1234567890","name":"JohnDoe","iat":1516239022}




      生成的JWT为:


      eyJ0eXAiOiJKV1QiLCJhbGciOiJub25lIn0.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG5Eb2UiLCJpYXQiOjE1MTYyMzkwMjJ9.


      可以发现,此时的JWT从三段数据变成了两段数据,SIGNATURE部分的数据被置空,此时若该JWT和正常生成的JWT一样有效,则证明存在允许空加密算法漏洞。


      2.修改RSA加密算法为HMAC攻击:如果alg原本为RSA算法,可以修改为HS256算法,即通知服务器使用公钥对签名进行校验。该攻击手法需要事先获取到RSA算法的公钥密钥(RSA算法的公钥),然后使用公钥密钥对HEADER和PAYLOAD的部分使用生成公式生成JWT。


      可以使用github开源环境https://github.com/Sjord/jwtdemo搭建demo进行测试。




      此时若该JWT和正常生成的JWT一样有效,则证明存在加密算法篡改漏洞。


      3.密钥爆破攻击:和账号密码爆破一样,由于JWT中的签名是使用密钥生成的,所以生成签名的密钥也是可以爆破的。JWT密钥爆破的不同点在于,首先需要一个有效的JWT才可以进行爆破。当爆破成功后,就可以使用密钥伪造其他用户身份的JWT。


      下载github开源脚本https://github.com/ticarpi/jwt_tool


      使用该脚本即可快速进行JWT密钥的爆破


      pythonjwt_tool.pyeyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJ1c2VyIjoiYWRtaW4iLCJhY3Rpb24iOiJ1cGxvYWQifQ.7ZbwdZXwfjm575fHGukkE09O8-eFY4bx-fEEBUK3XUE-C -d 1.txt


      密钥爆破和密码爆破一样,需要指定一个密钥字典文件。




      密钥爆破成功后即可用密钥伪造任意用户身份的JWT。




      04JWT安全


      1.开发时设置JWT签名校验密钥为强密钥,禁止使用弱密钥,且不同的系统要使用不同的密钥;


      2.开发时要对JWT进行充分校验,防止空算法、HMAC算法替换RSA算法等;


      3.定期对业务代码进行安全审计,防止由于其他安全漏洞造成密钥泄露等。

      免费试用
      服务热线

      马上咨询

      400-811-3777

      回到顶部