渗透测试之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
pip install PyJWT # 安装 jwt
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
<!-- https://mvnrepository.com/artifact/io.jsonwebtoken/jjwt --> <dependency><groupId>io.jsonwebtoken</groupId><artifactId>jjwt</artifactId><version>0.9.1</version> </dependency> -
生成 Token
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();} -
解密验证
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
<?phpclass 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, '-_', '+/'));} }说明:
-
生成 JWT:
使用 generateJWT($payload) 方法生成 JWT。
header 包含签名算法信息(这里使用 HS256),payload 包含用户信息或其他声明。
用 hash_hmac(‘sha256’) 方法签名生成的 JWT。 -
验证 JWT:
使用 verifyJWT($token) 方法验证 JWT。
验证签名是否正确,以及 payload 中是否设置了过期时间(可选)。 -
Base64 编码/解码:
使用 base64UrlEncode() 和 base64UrlDecode() 实现 URL 安全的 Base64 编码。
-
JWT Token 破解
jwt 破解关键在于获取到对应的秘钥,如果秘钥较为简单可以直接使用密码字典进行破解。现介绍以下几种秘钥破解工具
jwt-tool
是一个由python编写的,用于验证、伪造、扫描和篡改 JWT(JSON Web Tokens)的工具包,该工具包包含了一下功能:
- 测试已知漏洞
- 检查令牌的有效性
- 扫描配置错误或已知弱点
- 模糊测试声明值以引发意外行为
- 测试密钥/文件/公钥/JWKS 密钥的有效性
- 通过高速字典攻击识别弱密钥
- 伪造新的令牌头部和有效载荷内容,并使用密钥或通过其他攻击方法创建新签名
- 时间戳篡改
- RSA 和 ECDSA 密钥生成及重建(从 JWKS 文件)
特点:速度快
安装:
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 令牌的秘密密钥,从而让你伪造有效的令牌。
特点:无需字典,破解速度慢
安装:
git clone https://github.com/brendan-rius/c-jwt-cracker # 从github克隆代码
apt-get install libssl-dev # 安装 libssl-dev
make # 手动编译
运行:
/jwtcrack eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VybmFtZSI6InVzZXIifQ.rDR715B_5LxTmmxeU2pTXEP_6EaWKq2U50jFXIKeY9Y

运行完成后可得到秘钥
编码新的JWT Token
- 打开网站 https://www.bejson.com/jwt/
- 使用原有的 JWT Token 解码出 Header 和 Payload
- 将工具解析出来的秘钥填写在右侧秘钥栏中
- 点击编码按钮获得新的 JWT Token

