jwt 私钥_基于JWT的token弱密钥爆破

本文探讨了JWT(JSON Web Token)的身份验证机制,指出JWT的签名私钥(SECRET)的安全性至关重要。解释了JWT的构成,包括头部、载荷和签名,并展示了Java生成和验证JWT的代码示例。同时,提到了使用pyjwt库进行签名校验时可能出现的情况,并警告开发者注意防止弱密钥被爆破,以避免伪造token的风险。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

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 header = new HashMap();

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发生跨域攻击。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值