美文网首页jwt
基于JWT的token弱密钥爆破

基于JWT的token弱密钥爆破

作者: littlebin404 | 来源:发表于2019-12-12 11:11 被阅读0次

    JSON Web Token(JWT)是目前最流行的跨域身份验证解决方案。直接根据token取出保存的用户信息,以及对token可用性校验,大大简化单点登录。

    JWT=header+payload+signature(以.相隔)

    例:eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJleHAiOjE1NzYxMTk2NTYsInVzZXJuYW1lIjoiemRqIiwicGFzc3dvcmQiOiIxMjMifQ.ud_qtIYt3QywJkmjPZIXVPaW3SnWCFj9dLVYa7iTEIg

    下面详细介绍一下每个部分。

    头部(Header)

    用于描述关于该JWT的最基本的信息,例如其类型以及签名所用的算法等。

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

    BASE64编码后为:eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9

    载荷(playload)

    (1)标准中注册的声明(建议但不强制使用)

    (2)公共的声明

    (3)私有的声明(过期时间,用户名等信息)

    {"exp":1576119656,"username":"zdj","password":"123"}

    BASE64编码后:eyJleHAiOjE1NzYxMTk2NTYsInVzZXJuYW1lIjoiemRqIiwicGFzc3dvcmQiOiIxMjMifQ

    签名(signature)

    header(base64)+payload(base64)使用.连接组成的字符串,然后通过header中声明的加密方式进行加盐secret组合加密,然后就构成了jwt的第三部分

    ud_qtIYt3QywJkmjPZIXVPaW3SnWCFj9dLVYa7iTEIg

    注:secret是保存在服务器端的签名私钥,就是我们今天的主角;

    基于java实现JWT:

    生成token:

    public static String Generatetoken(String username, String password) {

    String token = "";

    try {

    // 过期时间

    Date date = new Date(System.currentTimeMillis() + EXPIRE_DATE);

    // 秘钥及加密算法

    Algorithm algorithm = Algorithm.HMAC256(TOKEN_SECRET);

    // 设置头部信息

    Map<String, Object> header = new HashMap<String, Object>();

    header.put("typ", "JWT");

    header.put("alg", "HS256");

    // 携带username,password信息,生成签名

    token = JWT.create().withHeader(header)

    .withClaim("username", username)

    .withClaim("password", password).withExpiresAt(date)

    .sign(algorithm);

    } catch (Exception e) {

    e.printStackTrace();

    return null;

    }

    return token;

    }

    校验token:

    public static boolean verify(String token) {

    try {

    Algorithm algorithm = Algorithm.HMAC256(TOKEN_SECRET);

    JWTVerifier verifier = JWT.require(algorithm).build();

    System.out.println("验证token:" + token);

    DecodedJWT jwt = verifier.verify(token);

    return true;

    } catch (Exception e) {

    e.printStackTrace();

    return false;

    }

    }

    生成的token为

    eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJleHAiOjE1NzYxMTk2NTYsInVzZXJuYW1lIjoiemRqIiwicGFzc3dvcmQiOiIxMjMifQ.ud_qtIYt3QywJkmjPZIXVPaW3SnWCFj9dLVYa7iTEIg

    综上,我们要伪造token,首先要拿到TOKEN_SECRET,才可以伪造签名,token才能校验通过。

    pyjwt 库,可通过 jwt.decode(jwt_str, verify=True, key=key_)

    进行签名校验,但导致校验失败的因素不仅密钥错误,还可能是数据部分中预定义字段错误(如,当前时间超过 exp),也可能是 JWT字符串格式错误等等,所以,借助 jwt.decode(jwt_str, verify=True, key=key_) 验证密钥 key_:

    1.若签名直接校验失败,则 key_ 为有效密钥;

    2.若因数据部分预定义字段错误

    (jwt.exceptions.ExpiredSignatureError,

    jwt.exceptions.InvalidAudienceError,

    jwt.exceptions.InvalidIssuedAtError,

    jwt.exceptions.InvalidIssuedAtError,

    jwt.exceptions.ImmatureSignatureError)导致校验失败,说明并非密钥错误导致,则 key_ 也为有效密钥;

    3.若因密钥错误(jwt.exceptions.InvalidSignatureError)导致校验失败,则 key_ 为无效密钥;

    4.若为其他原因(如,JWT 字符串格式错误)导致校验失败,根本无法验证当前 key_ 是否有效。

    按此逻辑,快速实现 JWT 密钥暴破功能,代码如下:

    爆破弱密钥脚本

    准备好key.txt字典,目标token为:eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJleHAiOjE1NzYxMjE1NDcsInVzZXJuYW1lIjoiemRqIiwicGFzc3dvcmQiOiIxMjMifQ.mkCLR5Kje9x-z8hRgWBMxnQm8hknOwV1Zd8uSZa3rQY,运行脚本进行爆破:

    无法获取到key
    获取到key

    总结

    因此,开发员要十分注意token的密钥强度,不然攻击者可以通过pyjwt爆破得到token密钥,通过header和payload进行signature,进而伪造token发生跨域攻击。

    相关文章

      网友评论

        本文标题:基于JWT的token弱密钥爆破

        本文链接:https://www.haomeiwen.com/subject/mwvzgctx.html