文章目录
Cookie
HTTP协议中的Cookie包括Web Cookie 和浏览器Cookie ,它是服务器发送到Web浏览器的一小块数据。服务器发送到浏览器的Cookie,浏览器会进行存储,并与下一个请求一起发送到服务器。通常,它用于判断两个请求是否来自于同一个浏览器,例如用户保持登录状态。HTTP Cookie机制是HTTP协议无状态的一种补充和改良。
Cookie主要用于下面三个目的:
- 会话管理:登录、购物车、游戏得分或者服务器应该记住的内容
- 个性化:用户偏好、主题或者其他设置
- 追踪:记录分析用户行为
创建Cookie
当接收到客户端发出的HTTP请求时,服务器可以发送带有响应的Set-Cookie
标头, Cookie 通常由浏览器存储,然后将Cookie与HTTP标头一同向服务器发出请求。可以指定到期日期或持续时间,之后将不再发送Cookie。此外,可以设置对特定域和路径的限制,从而限制cookie的发送位置。
Set-Cookie和Cookie标头
Set-Cookie
HTTP 响应标头将cookie从服务器发送到用户代理。下面是一个发送Cookie的例子
HTTP/2.0 200 OK
Content-type: text/html
Set-Cookie: yummy_cookie=choco
Set-Cookie: tasty_cookie=strawberry
此标头告诉客户端存储Cookie,现在,随着对服务器的每个新请求,浏览器将使用Cookie头将所有以前存储的cookie发送回服务器。
GET /sample_.page.html HTTP/2.0
Host: www.example.org
Cookie: yummy_cookie=choco; tasty_cookie=strawberry
Cookie主要分为三类,它们是会话Cookie 、永久Cookie 和Cookie的 Secure 和HttpOnly 标记,下面依次来介绍一下
会话Cookie
上面的示例创建的是会话Cookie,会话Cookie有个特征,客户端关闭时Cookie会删除,因为它没有指定Expires或Max- Age指令。但是,Web浏览器可能会使用会话还原,这会使大多数会话Cookie保持永久状态,就像从未关闭过浏览器一样。
永久Cookie
久性Cookie不会在客户端关闭时过期,而是在特定日期(Expires) 或特定时间长度(Max-Age) 外过期。例如
Set-Cookie: id=a3fWa;Expires=Wed,21 0ct 2015 07:28:00 GMT;
Cookie的 Secure 和HttpOnly 标记
安全的Cookie需要经过HTTPS协议通过加密的方式发送到服务器。即使是安全的,也不应该将敏感信息存储在cookie中,因为它们本质上是不安全的,并且此标志不能提供真正的保护。
HttpOnly的作用:
- 会话cookie中缺少HttpOnly属性会导致攻击者可以通过程序(JS脚本、Applet等)获取到用户的cookie信息,造成用户cookie信息泄露,增加攻击者的跨站脚本攻击威胁。
- HttpOnly是微软对cookie做的扩展,该值指定cookie是否可通过客户端脚本访问。
- 如果在Cookie中没有设置HttpOnly属性为true,可能导致Cookie被窃取。窃取的Cookie可以包含标识站点用户的敏感信息,如ASP.NET会话ID或Forms身份验证票证,攻击者可以重播窃取的Cookie,以便伪装成用户或获取敏感信息,进行跨站脚本攻击等。
Cookie作用域
Domain
和Path
标识定义了Cookie的作用域:即Cookie应该发送给哪些URL。
Domain
标识指定了哪些主机可以接受Cookie。如果不指定,默认为当前主机(不包含子域名)。如果指定了Domain
,则一般包含子域名。
例如,如果设置Domain=mozilla.org
,则Cookie也包含在子域名中(如developer.mozilla.org
)。
例如,设置Path=/docs
,则以下地址都会匹配:
/docs
/docs/Web/
/docs/Web/Http/
Session
客户端请求服务端,服务端会为这次请求开辟一块内存空间,这个对象便是Session对象,存储结构为ConcurrentHashMap
。Session 弥补了HTTP无状态特性,服务器可以利用Session存储客户端在同一个会话期间的一些操作记录。
Session如何判断是否是同一会话
服务器第一次接收到请求时,开辟了一块Session空间(创建了Session对象),同时生成一个sessionld,并通过响应头的Set-Cookie: JSESSIONID=XXXXXXX命令,向客户端发送要求设置Cookie的响应;客户端收到响应后,在本机客户端设置了一个JSESSIONID=XXXXXXX的Cookie信息,该Cookie的过期时间为浏览器会话结束;
接下来客户端每次向同一个网站发送请求时,请求头都会带上该Cookie信息(包含 sessionld),然后,服务器通过读取请求头中的Cookie信息,获取名称为JSESSIONID的值,得到此次请求的sessionld。
Session的缺点
Session机制有个缺点,比如A服务器存储了Session, 就是做了负载均衡后,假如一段时间内A的访问量激增,会转发到B进行访问,但是B服务器并没有存储A的Session,会导致Session的失效。
JSON Web Token和Session Cookies的对比
JSON Web Token,简称JWT ,它和Session 都可以为网站提供用户的身份认证,但是它们不是一回事。
什么是Session Cookies
Session Cookies也称为会话Cookies,在Session Cookies中,用户的登录状态会保存在服务器的内存中。当用户登录时,Session 就被服务端安全的创建。在每次请求时,服务器都会从会话Cookie中读取sessionld,如果服务端的数据和读取的sessionld相同,那么服务器就会发送响应给浏览器,允许用户登录。
什么是Json Web Token
Json Web Token的简称就是JWT,通常可以称为Json 令牌。它是RFC 7519中定义的用于安全的将信息作为Json 对象进行传输的一种形式。JWT中存储的信息是经过数字签名的,因此可以被信任和理解。可以使用HMAC算法或使用RSAECDSA的公用/专用密钥对JWT进行签名。使用JWT主要用来下面两点:
- 认证(Authorization) :这是使用JWT最常见的一种情况,一旦用户登录,后面每个请求都会包含JWT,从而允许用户访问该令牌所允许的路由、服务和资源。单点登录是当今广泛使用JWT的一项功能,因为它的开销很小。
- 信息交换(Information Exchange) : JWT是能够安全传输信息的一种方式。通过使用公钥/私钥对JWT进行签名认证。此外,由于签名是使用head 和payload 计算的,因此你还可以验证内容是否遭到篡改。
JWT主要由三部分组成,每个部分用 . 进行分割, 各个部分分别是:Header、Payload、Signature
示例:
eyJhbGci0iJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIi0iIxMjMONTY3ODkwIiwibmFtZSI6IkpvaG4gR
G91IiwiYWRtaW4iOnRydWV9.TJVA950rM7E2cBab3ORMHrHDcEfxjoYZgeFONFh7HgQ
JWT和Session Cookies的相同之处
它们既可以对用户进行身份验证,也可以用来在用户单击进入不同页面时以及登陆网站或应用程序后进行身份验证。如果没有这两者,那你可能需要在每个页面切换时都需要进行登录了。因为HTTP是一个无状态的协议。这也就意味着当你访问某个网页,然后单击同一站点上的另一个页面时,服务器的内存中将不会记住你之前的操作。
JWT和Session Cookies就是用来处理在不同页面之间切换,保存用户登录信息的机制。也就是说,这两种技术都是用来保存你的登录状态,能够让你在浏览任意受密码保护的网站。通过在每次产生新的请求时对用户数据进行身份验证来解决此问题。
JWT和Session Cookies的不同之处
- 密码签名:JWT具有加密签名,而Session Cookies则没有。
- JWT是无状态的:JWT是无状态的,因为声明被存储在客户端,而不是服务端内存中。身份验证可以在本地进行,而不是在请求必须通过服务器数据库或类似位置中进行。这意味着可以对用户进行多次身份验证,而无需与站点或应用程序的数据库进行通信,也无需在此过程中消耗大量资源。
- 可扩展性:Session Cookies是存储在服务器内存中,这就意味着如果网站或者应用很大的情况下会耗费大量的资源。由于JWT是无状态的,在许多情况下,它们可以节省服务器资源。因此JWT要比Session Cookies具有更强的可扩展性。
- JWT支持跨域认证:Session Cookies只能用在单个节点的域或者它的子域中有效。如果它们尝试通过第三个节点访问,就会被禁止。如果你希望自己的网站和其他站点建立安全连接时,这是一个问题。使用JWT可以解决这个问题,使用JWT能够通过多个节点进行用户认证,也就是我们常说的跨域认证。
JWT和Session Cookies的选型
对于只需要登录用户并访问存储在站点数据库中的一些信息的中小型网站来说,Session Cookies 通常就能满足。如果你有企业级站点,应用程序或附近的站点,并且需要处理大量的请求,尤其是第三方或很多第三方(包括位于不同域的API),则JWT显然更适合。
HTTPS
HTTPS 是HTTP协议的一种扩展,它本身并不保传输的安全性,那么谁来保证安全性呢?在HTTPS中,使用传输层安全性(TLS)或安全套接字层(SSL)对通信协议进行加密。也就是**HTTP + SSL(TLS)= HTTPS。**默认端口443。
HTTPS并不是一项新的应用层协议,只是HTTP通信接口部分由SSL和TLS替代而已。通常情况下,HTTP会先直接和TCP进行通信。在使用SSL的HTTPS后,则会先演变为和SSL进行通信,然后再由SSL和TCP进行通信。也就是说,HTTPS 就是身披了一层SSL的HTTP。SSL是一个独立的协议,不只有HTTP可以使用,其他应用层协议也可以使用,比如SMTP
(电子邮件协议)、Telnet
(远程登录协议) 等都可以使用。
HTTPS协议提供了三个关键的指标:
- 加密(Encryption) ,HTTPS通过对数据加密来使其免受窃听者对数据的监听,这就意味着当用户在浏览网站时,没有人能够监听他和网站之间的信息交换,或者跟踪用户的活动,访问记录等,从而窃取用户信息。
- 数据一致性(Data integrity) ,数据在传输的过程中不会被窃听者所修改,用户发送的数据会完整的传输到服务端,保证用户发的是什么,服务器接收的就是什么。
- 身份认证(Authentication),是指确认对方的真实身份,也就是证明你是你,它可以防止中间人攻击并建立用户信任。
有了上面三个关键指标的保证,用户就可以和服务器进行安全的交换信息了。
什么是SSL/TLS
TLS(Transport Layer Security)
是SSL(Secure Socket Layer)
的后续版本,它们是用于在互联网两台计算机之间用于身份验证和加密的一种协议。TLS由记录协议、握手协议、警告协议、变更密码规范协议、扩展协议等几个子协议组成,综合使用了对称加密、非对称加密、身份认证等许多密码学前沿技术。
举一个TLS例子来看一下TLS的结构:
ECDHE-ECDSA-AES256-GCM-SHA384
TLS的密码套件比较规范,基本格式就是密钥交换算法-签名算法-对称加密算法-摘要算法组成的一个密码串,有时候还有分组模式,我们先来看一下上面是什么意思:使用ECDHE进行密钥交换,使用ECDSA进行签名和认证,然后使用AES作为对称加密算法,密钥的长度是256位,使用GCM作为分组模式,最后使用SHA384作为摘要算法。
TLS在根本上使用对称加密和非对称加密两种形式 。
SSL/TLS握手过程
TLS旨在为Internet 提供通信安全的加密协议。TLS握手是启动和使用TLS加密的通信会话的过程。在TLS握手期间,Internet 中的通信双方会彼此交换信息,验证密码套件,交换会话密钥。每当用户通过HTTPS导航到具体的网站并发送请求时,就会进行TLS握手。除此之外,每当其他任何通信使用HTTPS (包括API调用和在HTTPS上查询DNS)时,也会发生TLS握手。TLS具体的握手过程会根据所使用的密钥交换算法的类型和双方支持的密码套件而不同。我们以RSA非对称加密来讨论这个过程。整个TLS通信流程图如下:
- 在进行通信前,首先会进行HTTP的三次握手,握手完成后,再进行TLS的握手过程。
- ClientHello:客户端通过向服务器发送hello 消息来发起握手过程。这个消息中会夹带着客户端支持的TLS版本号(TLS1.0 、TLS1.2、TLS1.3)、客户端支持的密码套件、以及一串客户端随机数。
- ServerHello:在客户端发送hello消息后,服务器会发送一条消息,这条消息包含了服务器的SSL证书、服务器选择的密码套件和服务器生成的随机数。
- 认证(Authentication):客户端的证书颁发机构会认证SSL证书,然后发送Certificate 报文,报文中包含公开密钥证书。最后服务器发送ServerHelloDone 作为hello 请求的响应。第一部分握手阶段结束。
- 加密阶段:在第一个阶段握手完成后,客户端会发送
ClientKeyExchange
作为响应,这个响应中包含了一种称为The premaster secret
的密钥字符串,这个字符串就是使用上面公开密钥证书进行加密的字符串。随后客户端会发送ChangeCipherSpec
,告诉服务端使用私钥解密这个premaster secret
的字符串,然后客户端发送Finished
告诉服务端自己发送完成了。 - 实现了安全的非对称加密:然后,服务器再发送
ChangeCipherSpec
和Finished
告诉客户端解密完成,至此实现了RSA的非对称加密。