Python 3.x 如何在Python3.7中编辑JWT头?
我正在尝试编写一个程序,该程序将试图通过单词列表强制执行用于在JWT令牌中签名的秘密 问题是,每当我使用PyJWT生成令牌时,头(在base64解码之后)是:Python 3.x 如何在Python3.7中编辑JWT头?,python-3.x,jwt,pyjwt,Python 3.x,Jwt,Pyjwt,我正在尝试编写一个程序,该程序将试图通过单词列表强制执行用于在JWT令牌中签名的秘密 问题是,每当我使用PyJWT生成令牌时,头(在base64解码之后)是:{“typ”:“JWT”,“alg”:“HS512”} 但我试图破解的大多数JWT令牌都有以下标题:{“alg”:“HS512”,“typ”:“JWT”} 这是我得到的代币: eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzUxMiJ9.eyJzb21lIjoicGF5bG9hZCJ9.EgMnzcJYrElON09Bw_Owa
{“typ”:“JWT”,“alg”:“HS512”}
但我试图破解的大多数JWT令牌都有以下标题:{“alg”:“HS512”,“typ”:“JWT”}
这是我得到的代币:
eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzUxMiJ9.eyJzb21lIjoicGF5bG9hZCJ9.EgMnzcJYrElON09Bw_OwaqR_Z7Cq30n7cgTZGJqtK1YHfG1cGnGJoJGwOLj6AWg9taOyJN3Dnqd9NXeTCjTCwA
正如可以预料的那样,散列签名将是不同的,我的程序将无法正常工作,我知道可以在头中添加更多数据,但不知道如何在“typ”和“alg”之间切换
任何帮助都将不胜感激,我希望继续使用python,而不是改用不同的编程语言。如果您打算对JWT进行暴力攻击(这将是一项巨大的任务,祝您好运),那么您只需直接从前两部分生成签名即可。Python字典和JSON对象都是无序结构,因此任何顺序都是有效的,JWT规范没有指定顺序,任何JWT实现都只需要前两部分的现有数据来验证签名。他们不会重新生成JSON PyJWT库在
jwt.algorithms
模块中将所有支持的算法作为单独的对象提供;只需调用jwt.algorithms.get_default_algorithms()
即可获得映射名称的字典
每个这样的对象都有.sign(msg,key)
和.verify(msg,key,sig)
方法。将前两个段(base64编码,使用
,作为字节
对象)作为消息传递,使用.sign()
或使用验证时,您将传入从base64数据解码的二进制签名(非base64编码)
因此,对于作为字节
对象的给定令牌
,您可以使用以下方法获取算法并验证密钥:
import json
from jwt.utils import base64url_decode
from jwt.algorithms import get_default_algorithms
algorithms = get_default_algorithms()
msg, _, signature_part = token.rpartition(b'.')
header = json.loads(base64url_decode(msg.partition(b'.')[0]))
algo = algorithms[header['alg']]
signature = base64url_decode(signature_part)
# bytes key from other source; brute-force or otherwise
if algo.verify(msg, key, signature):
# key correct
假设您的示例令牌
和密钥
设置为b'secret'
,则上述验证:
>>> import json
>>> from jwt.utils import base64url_decode
>>> from jwt.algorithms import get_default_algorithms
>>> token = b'eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzUxMiJ9.eyJzb21lIjoicGF5bG9hZCJ9.EgMnzcJYrElON09Bw_OwaqR_Z7Cq30n7cgTZGJqtK1YHfG1cGnGJoJGwOLj6AWg9taOyJN3Dnqd9NXeTCjTCwA'
>>> key = b'secret'
>>> algorithms = get_default_algorithms()
>>> msg, _, signature_part = token.rpartition(b'.')
>>> header = json.loads(base64url_decode(msg.partition(b'.')[0]))
>>> algo = algorithms[header['alg']]
>>> signature = base64url_decode(signature_part)
>>> algo.verify(msg, key, signature)
True
然后,通过在循环中生成密钥进行暴力强制是很容易验证的。请注意,任何超出一个小键(使用有限的字母表)的操作都将很快变得不可行;即使使用系统编程语言,一个16字节的完全随机键值(128位)也需要几十年的时间才能在现代硬件上强制执行,更不用说Python循环的较慢速度了。如果您要强制执行JWT(这将是一项巨大的任务,祝您好运),那么您只需自己直接生成签名,从前两部分开始。Python字典和JSON对象是无序结构,任何JWT实现都只需要前两部分的现有数据来验证签名。他们不会重新生成JSON。这并不意味着要与适当的jwt一起工作,它是为一个简单的秘密单词的练习而设计的。你的方法就像一个符咒,我想我一开始就不应该这样做。
>>> import json
>>> from jwt.utils import base64url_decode
>>> from jwt.algorithms import get_default_algorithms
>>> token = b'eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzUxMiJ9.eyJzb21lIjoicGF5bG9hZCJ9.EgMnzcJYrElON09Bw_OwaqR_Z7Cq30n7cgTZGJqtK1YHfG1cGnGJoJGwOLj6AWg9taOyJN3Dnqd9NXeTCjTCwA'
>>> key = b'secret'
>>> algorithms = get_default_algorithms()
>>> msg, _, signature_part = token.rpartition(b'.')
>>> header = json.loads(base64url_decode(msg.partition(b'.')[0]))
>>> algo = algorithms[header['alg']]
>>> signature = base64url_decode(signature_part)
>>> algo.verify(msg, key, signature)
True