JWT的认识与攻击

作者:网友投稿 时间:2018-05-15 21:31

字号

JWT ( JSON Web Token 的缩写)是一串带有声明信息的字符串,由服务端用加密算法对信息签名来保证其完整性和不可伪造。Token里可以包含所有必要信息,这样服务端就无需保存任何关于用户或会话的信息,JWT可用于身份认证、会话状态维持、信息交换等。

JWT 由三部分构成,分别称为 header 、payload 和 signature ,各部分用. 相连构成一个完整的Token,形如xxxxx.yyyyy.zzzzz 。

分别看下各个部分:

header

使用一个JSON格式字符串声明token的类型和签名用的算法等,形如{"alg": "HS256", "typ": "JWT"} 。该字符串经过Base64Url编码后形成JWT的第一部分xxxxx。

Base64Url编码可以用这段代码直观理解:


from base64 import *
def base64URLen(s):
t0=b64encode(s)
t1=t0.strip('=').replace('+','-').replace('/','_')
return t1

def base64URLde(s):
t0=s.replace('-','+').replace('_','/')
t1=t0+'='*(4-len(t0)%4)%4
return b64decode(t1) payload :

使用一个JSON格式字符串描述所要声明的信息,分为 registered 、public 、 和 private 三类,形如{"name": "John Doe", "admin": true} ,具体信息可参考 部分。

同样的,该字符串经过Base64Url编码形成JWT的第二部分yyyyy。

signature :

将 xxxxx.yyyyy 使用alg 指定的算法加密,然后再Base64Url编码得到JWT的第三部分zzzzz 。所支持的算法 类型取决于实现,但HS256 和 none 是强制要求实现的。

0×02 简单应用

在本地运行起简单的基于Express的可发放和处理JWT的服务。

安装Node.js。Node.js是JavaScript运行时环境,采用轻量高效的事件驱动、无阻塞I/O模型,拥有最大的开源库生态nmp。

Windows平台可在 https://nodejs.org/en/download/ 下载安装包
*nix 平台可根据 https://nodejs.org/en/download/package-manager/ 提示使用包管理器安装

安装Express,一款基于Node.js的快速、灵活、极简的Web框架。

#
mkdir D:\myapp && cd D:\myapp
(全部回车,保持默认配置)
npm init
npm install express --save

运行本地服务

新建 index.js ,内容如下

const express = require('express')
const app = express()
app.get('/', (req, res) => res.send('Hello World!'))
app.listen(3000, () => console.log('Example app listening on port 3000!'))

运行node index.js ,就可从本地访问 :3000 。

安装必要模块: 适用于Node.js的JWT编解码模块 node-jwt-simple 和 cookie解析模块 cookie-parser

# https://github.com/hokaccha/node-jwt-simple
npm install jwt-simple
npm install cookie-parser

一个简单的本地demo

//index.js
//http://expressjs.com/en/4x/api.html
//https://github.com/hokaccha/node-jwt-simple

//一些初始化的工作
const express = require('express')
var jwt = require('jwt-simple')
var cookieParser = require('cookie-parser')
var jwt_secret = "this is a secret for jwt"
const app = express()
app.use(cookieParser())

app.get('/',(req,res)=>res.redirect('/help'))
app.get('/help', (req, res) => {
var RequstedURL=req.protocol+'://'+req.get('Host')
res.send([
'GET '+RequstedURL+'/login?user=name&pass=passwd to get your JSON Web Token ' ,
'GET '+RequstedURL+'/whoami to identify yourself'
].join('<br>'))
})

app.get('/login',(req,res)=>{
var users={
"admin":"admin_password_is_hard_to_guess",
"test":"test123"
}
var payload = {"name":req.query.user}
if(users[req.query.user]===req.query.pass){
res.cookie('jwt',jwt.encode(payload,jwt_secret))
res.send(req.query.user +' logged in')
}
else{res.send('login failed!')}
})

app.get('/whoami',(req,res)=>{
try {res.send("you are logged in as :<br>" +jwt.decode(req.cookies.jwt,jwt_secret)['name'])}
catch(err) {res.send("your JWT is :<br>"+req.cookies.jwt)}
})

app.listen(3000, () => {
console.log('Example app listening on port 3000!');
console.log('Example app listening on port 3000!')
})

推荐几个在线工具

https://jwt.io

by Sjoerd Langkemper

支持 hs256 算法

支持 rs256 算法

by Kenji Urushima

支持更多算法 kjur/jsjws

0×03 攻击面 发现敏感信息
责任编辑:CQITer新闻报料:400-888-8888   本站原创,未经授权不得转载
关键词 >>JWT 专栏
继续阅读
热新闻
推荐
关于我们联系我们免责声明隐私政策 友情链接