渗透测试之json_web_token(JWT)

JSON Web Tokens

JWT官方文档:https://www.jwt.io/introduction#what-is-json-web-token

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

了解JWT: https://blog.csdn.net/weixin_65211978/article/details/126894056

创建和验证 JWT token

++注意:使用的秘钥需要相对复制,否则容易被破解++

python

shell 复制代码
pip install PyJWT  # 安装 jwt 
python 复制代码
import jwt
# jwt加密 (payload 数据, 秘钥信息, 加密算法)
jwt.encode({'username': 'admin'}, 'admin', algorithm='HS256')  
# jwt解密 (JWT Token, 秘钥, 加密算法)
jwt.decode(self.get_cookie("jwt_demo").encode('utf-8'), jwt_secret, algorithms=['HS256'])  

java

https://blog.csdn.net/weixin_44494373/article/details/113173326

导入maven
xml 复制代码
<!-- https://mvnrepository.com/artifact/io.jsonwebtoken/jjwt -->
<dependency>
    <groupId>io.jsonwebtoken</groupId>
    <artifactId>jjwt</artifactId>
    <version>0.9.1</version>
</dependency>
生成 Token
java 复制代码
public static String tokens(Map<String, Object> claims, String secretKey, int millisecond, String jwtIssuer, String jwtAud) {

       //获取当前的时间
       Calendar calendar = Calendar.getInstance();
       Date date = new Date(System.currentTimeMillis());
       calendar.setTime(date);
       //向后退后秒数
       calendar.add(Calendar.MILLISECOND, millisecond);
       Date endTime = calendar.getTime();
       JwtBuilder builder = Jwts.builder().setClaims(claims)
               .signWith(SignatureAlgorithm.HS256, secretKey)
               .setClaims(claims)
               .setIssuedAt(new Date())
               .setExpiration(endTime)
               .setIssuer(jwtIssuer)
               .setAudience(jwtAud);
       return builder.compact();
   }
解密验证
java 复制代码
public static Claims parse(String jwt, String secretKey) throws JwtExpireException, JwtVerifyException , JwtNotExistException{
       Claims claims = null;
       try {
           claims = Jwts.parser().setSigningKey(secretKey).parseClaimsJws(jwt).getBody();
       } catch (ExpiredJwtException expiredJwtException) {
           throw new ExpiredJwtException("token过期");
       } catch (JwtException jwtException) {
           throw new JwtException("JWT验证错误");
       } catch (IllegalArgumentException illegalArgumentException) {
           throw new IllegalArgumentException("Token为空");
       }
       return claims;
   }

php

https://blog.csdn.net/Crazy_shark/article/details/142147246

php 复制代码
<?php
 
class JWT
{
    private static $secretKey = 'your_secret_key'; // 加密使用的秘钥
    private static $algo = 'HS256';  // 使用的算法
 
    /**
     * 生成JWT
     * 
     * @param array $payload 数据负载
     * @return string
     */
    public static function generateJWT($payload)
    {
        // 1. 生成header
        $header = json_encode(['alg' => self::$algo, 'typ' => 'JWT']);
        $base64Header = self::base64UrlEncode($header);
 
        // 2. 生成payload
        $base64Payload = self::base64UrlEncode(json_encode($payload));
 
        // 3. 生成signature
        $signature = hash_hmac('sha256', "$base64Header.$base64Payload", self::$secretKey, true);
        $base64Signature = self::base64UrlEncode($signature);
 
        // 4. 组合JWT
        $jwt = "$base64Header.$base64Payload.$base64Signature";
 
        return $jwt;
    }
 
    /**
     * 验证JWT
     * 
     * @param string $token JWT令牌
     * @return array|bool 如果验证成功返回payload,否则返回false
     */
    public static function verifyJWT($token)
    {
        // 1. 拆分JWT
        $parts = explode('.', $token);
        if (count($parts) !== 3) {
            return false;
        }
 
        list($base64Header, $base64Payload, $base64Signature) = $parts;
 
        // 2. 解码Header和Payload
        $header = json_decode(self::base64UrlDecode($base64Header), true);
        $payload = json_decode(self::base64UrlDecode($base64Payload), true);
        $signature = self::base64UrlDecode($base64Signature);
 
        // 3. 验证签名
        $expectedSignature = hash_hmac('sha256', "$base64Header.$base64Payload", self::$secretKey, true);
        if (!hash_equals($signature, $expectedSignature)) {
            return false;
        }
 
        // 4. 验证过期时间
        if (isset($payload['exp']) && $payload['exp'] < time()) {
            return false;
        }
 
        return $payload;
    }
 
    /**
     * Base64URL编码
     * 
     * @param string $data
     * @return string
     */
    private static function base64UrlEncode($data)
    {
        return rtrim(strtr(base64_encode($data), '+/', '-_'), '=');
    }
 
    /**
     * Base64URL解码
     * 
     * @param string $data
     * @return string
     */
    private static function base64UrlDecode($data)
    {
        return base64_decode(strtr($data, '-_', '+/'));
    }
}

说明:

  1. 生成 JWT:

    使用 generateJWT($payload) 方法生成 JWT。

    header 包含签名算法信息(这里使用 HS256),payload 包含用户信息或其他声明。

    用 hash_hmac('sha256') 方法签名生成的 JWT。

  2. 验证 JWT:

    使用 verifyJWT($token) 方法验证 JWT。

    验证签名是否正确,以及 payload 中是否设置了过期时间(可选)。

  3. Base64 编码/解码:

    使用 base64UrlEncode() 和 base64UrlDecode() 实现 URL 安全的 Base64 编码。

JWT Token 破解

jwt 破解关键在于获取到对应的秘钥,如果秘钥较为简单可以直接使用密码字典进行破解。现介绍以下几种秘钥破解工具

jwt-tool

是一个由python编写的,用于验证、伪造、扫描和篡改 JWT(JSON Web Tokens)的工具包,该工具包包含了一下功能:

  • 测试已知漏洞
  • 检查令牌的有效性
  • 扫描配置错误或已知弱点
  • 模糊测试声明值以引发意外行为
  • 测试密钥/文件/公钥/JWKS 密钥的有效性
  • 通过高速字典攻击识别弱密钥
  • 伪造新的令牌头部和有效载荷内容,并使用密钥或通过其他攻击方法创建新签名
  • 时间戳篡改
  • RSA 和 ECDSA 密钥生成及重建(从 JWKS 文件)

特点:速度快

安装:
shell 复制代码
git clone https://github.com/ticarpi/jwt_tool  # 从github克隆工具
python3 -m pip install -r requirements.txt  # 安装相关依赖

首次运行时,工具会生成一个配置文件、一些工具文件、日志文件以及一套不同格式的公钥和私钥。

使用方法:

python3 jwt_tool.py <JWT> 将验证令牌并列出头部和载荷的值。
python3 jwt_tool.py <JWT> -T 篡改现有令牌,更改令牌中 header 和 payload 的信息,根据提示进行相关修改
python3 jwt_tool.py <JWT> -C -p pass.txt 根据提供的字典识别弱秘钥
python3 jwt_tool.py <JWT> -V -pk public.pem 验证令牌,需要提供额外的参数/文件(此处提供 PEM 格式的公钥)

c-jwt-cracker

一个用 C 语言编写的多线程 JWT 暴力破解工具。如果你非常幸运或者拥有强大的计算能力,这个程序应该能找到 JWT 令牌的秘密密钥,从而让你伪造有效的令牌。

特点:无需字典,破解速度慢

安装:
shell 复制代码
git clone https://github.com/brendan-rius/c-jwt-cracker  # 从github克隆代码
apt-get install libssl-dev  # 安装 libssl-dev
make  # 手动编译 
运行:
shell 复制代码
/jwtcrack eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VybmFtZSI6InVzZXIifQ.rDR715B_5LxTmmxeU2pTXEP_6EaWKq2U50jFXIKeY9Y

运行完成后可得到秘钥

编码新的JWT Token

  1. 打开网站 https://www.bejson.com/jwt/
  2. 使用原有的 JWT Token 解码出 HeaderPayload
  3. 将工具解析出来的秘钥填写在右侧秘钥栏中
  4. 点击编码按钮获得新的 JWT Token
相关推荐
云动雨颤2 小时前
网站被劫持后怎么恢复?
安全·dns
北京耐用通信3 小时前
冶金车间“迷雾”重重?耐达讯自动化Profibus转光纤为HMI点亮“透视眼”!
人工智能·物联网·网络协议·网络安全·自动化
北京耐用通信3 小时前
耐达讯自动化Profibus光纤模块:智能仪表的“生命线”,极端环境通信无忧!
人工智能·物联网·网络协议·自动化·信息与通信
m0_738120723 小时前
内网横向靶场——记录一次横向渗透(三)
开发语言·网络·安全·web安全·网络安全·php
Jerry2505094 小时前
微信小程序必要要安装SSL证书吗?小程序SSL详解
网络·网络协议·网络安全·微信小程序·小程序·https·ssl
大G的笔记本5 小时前
gRPC vs RPC 高频面试题
网络·网络协议·rpc
codervibe5 小时前
协议欺骗工程实践:HTTP/FTP/Telnet/SSH 的伪装与实现要点
安全
软件供应链安全指南6 小时前
“基于‘多模态SCA+全周期协同’的中间件开源风险治理实践”荣获OSCAR开源+安全及风险治理案例
安全·中间件·开源