JWT

  • JWT已关闭评论
  • 5 views
  • A+
所属分类:安全闲碎

JWT的全称是Json Web Token。它遵循JSON格式,将用户信息加密到token里,服务器不保存任何用户信息,只保存密钥信息,通过使用特定加密算法验证token,通过token验证用户身份。基于token的身份验证可以替代传统的cookie+session身份验证方法。

JWT由三个部分组成:header.payload.signature

header部分最常用的两个字段是algtypalg指定了token加密使用的算法(最常用的为HMACRSA算法),typ声明类型为JWT。

payload则为用户数据以及一些元数据有关的声明,用以声明权限。

signature的功能是保护token完整性。

生成方法为将header和payload两个部分联结起来,然后通过header部分指定的算法,计算出签名。

抽象成公式就是

signature = HMAC-SHA256(base64urlEncode(header) + '.' + base64urlEncode(payload), secret_key)

值得注意的是,编码header和payload时使用的编码方式为base64urlencodebase64url编码是base64的修改版,为了方便在网络中传输使用了不同的编码表,它不会在末尾填充”=”号,并将标准Base64中的”+”和”/“分别改成了”-“和”-“。


完整token生成

  • 在线

    https://jwt.io/

  • Python

    python的Pyjwt使用示例:

    1
    2
    3
    4
    5
    import jwt

    encoded_jwt = jwt.encode({'user_name': 'admin'}, 'key', algorithm='HS256')
    print(encoded_jwt)
    print(jwt.decode(encoded_jwt, 'key', algorithms=['HS256']))

攻击方式

  • 空加密算法

    JWT支持使用空加密算法,可以在header中指定alg为None

    这样的话,只要把signature设置为空(即不添加signature字段),提交到服务器,任何token都可以通过服务器的验证。举个例子,使用以下的字段

    1
    2
    3
    4
    5
    6
    7
    8
    {
    "alg" : "None",
    "typ" : "jwt"
    }

    {
    "user" : "Admin"
    }

    生成的完整token为ew0KCSJhbGciIDogIk5vbmUiLA0KCSJ0eXAiIDogImp3dCINCn0.ew0KCSJ1c2VyIiA6ICJBZG1pbiINCn0

    (header+’.’+payload,去掉了’.’+signature字段)

    空加密算法的设计初衷是用于调试的,但是如果某天开发人员脑阔瓦特了,在生产环境中开启了空加密算法,缺少签名算法,jwt保证信息不被篡改的功能就失效了。攻击者只需要把alg字段设置为None,就可以在payload中构造身份信息,伪造用户身份。

  • 修改RSA加密算法为HMAC

    JWT中最常用的两种算法为HMACRSA

    HMAC是密钥相关的哈希运算消息认证码(Hash-based Message Authentication Code)的缩写,它是一种对称加密算法,使用相同的密钥对传输信息进行加解密。

    RSA则是一种非对称加密算法,使用私钥加密明文,公钥解密密文。

    在HMAC和RSA算法中,都是使用私钥对signature字段进行签名,只有拿到了加密时使用的私钥,才有可能伪造token。

    现在我们假设有这样一种情况,一个Web应用,在JWT传输过程中使用RSA算法,密钥pem对JWT token进行签名,公钥pub对签名进行验证。

    1
    2
    3
    4
    {
    "alg" : "RS256",
    "typ" : "jwt"
    }

    通常情况下密钥pem是无法获取到的,但是公钥pub却可以很容易通过某些途径读取到,这时,将JWT的加密算法修改为HMAC,即

    1
    2
    3
    4
    {
    "alg" : "HS256",
    "typ" : "jwt"
    }

    同时使用获取到的公钥pub作为算法的密钥,对token进行签名,发送到服务器端。

    服务器端会将RSA的公钥(pub)视为当前算法(HMAC)的密钥,使用HS256算法对接收到的签名进行验证。

    1
    2
    3
    4
    5

    import jwt
    public = open('public.key', 'r').read()
    payload={"user":"admin"}
    print(jwt.encode(payload, key=public, algorithm='HS256'))

  • 爆破密钥

    对 JWT 的密钥爆破需要在一定的前提下进行:

    • 知悉JWT使用的加密算法
    • 一段有效的、已签名的token
    • 签名用的密钥不复杂(弱密钥)

    所以其实JWT 密钥爆破的局限性很大。

    相关工具:

    c-jwt-cracker

    ./jwtcrack [JWT]

    jwt_tool

    python3 jwt_tool.py [JWT]

    简单的字母数字组合都是可以爆破的,但是密钥位数稍微长一点或者更复杂一点的话,爆破时间就会需要很久。

    gojwtcrack

    ./gojwtcrack -t token.txt -d rockyou.txt

  • 其他

    参考:

    攻击JWT的一些方法

    Jwt认识与攻击

相关推荐: CentOS下tomcat安全配置

1. 安装后初始化配置当Tomcat完成安装后你首先要做的事情如下:首次安装完成后立即删除webapps下面的所有代码rm -rf /srv/apache-tomcat/webapps/*注释或删除 tomcat-users.xml 所有用户权限,看…

  • 版权声明:本站收录文章,于2021年10月11日22:37:14,由 发表,共 2275 字。
  • 转载请注明:JWT | CN-SEC 中文网