cookie、session、token的区别和相似点,JWT和数字签名以及签名证书的了解

cookie、session、token分别是什么?有啥区别呢?

为什么需要cookie、session、token呢?

        首先,要思考的是为啥有这三个东西,因为HTTP协议是无状态的特性导致的,什么是无状态性呢?就是比如客户端和服务端进行了一次请求和响应,协议只负责处理请求,拒绝响应之类的,但是不负责记忆,这样就有问题产生了,协议的拒绝或者响应肯定是需要验证的,但是协议本身没有记忆的能力,那么每次请求都去做验证显然是不合理的,就好比你逛淘宝每次去到一个新的页面都需要你进行登录验证,正常人都会心态爆炸啦,所以为了维持会话的进行,cookie和session就应运而生了,这也就是他的用途了,当然token也是同理,只是手段有些许差距。

cookie和session:

        首先讲的是cookie,第一点:①我们需要记住的是cookie是存储在客户端的,而session是存储在服务器的,这里这么理解,cookie就是钥匙放在客户的手上,服务端就是一个酒店,而session就是每一个门的门锁,门里面都有个服务员可以和客户对话,存贮位置不同是他们一个重要的区别,比如我们要进行一个会话,那肯定需要用钥匙打开对应的门才能继续会话,第二点:②cookie是有过期时间的,如果不设置,cookie就是当前游览器会话时间的话,游览器关了,cookie就过期了,如果设置了过期时间,cookie会被存贮在硬盘上,游览器关闭,下次打开cookie依旧存在,第三点:③cookie有大小的限制,单个cookie的大小是4kb,多数游览器限制一个站点最多可以存储20个cookie。第四点:④这里还有个需要注意的点就是cookie是以明文的形式存储的,存储方式为键值对,这样就暴露一个问题那就是隐私数据比如账号密码是不能存在于cookie的,不然很轻易就会被他人窃取,同样cookie也比较容易伪造,可以轻易修改cookie的数值,所以如果重要信息以明文的形式存储非常容易泄露被人利用。

        接下来说的是session,刚刚我将session比喻成门锁,可以更好理解cookie和session的对应关系,其实session也可以比作一个账单,在每一次会话的时候,session会将sessionID发送给客户端的cookie存储,下一次要进行会话的时候,cookie出示对应的账单号,session一个个去找,找到对应的就开始继续上一次的会话,这里为什么不用之前那个例子,其实是因为注意的是服务器根据客户端提供的cookie也就是账单号去找,如果是刚刚那个例子就变成客户端去找对应的门开了,不太合理,但是说到这里就埋下一个伏笔,那就是session需要去找到对应的账单号才能继续会话,那么服务器就必须在每一次请求协议都存出到他的内存中去,如果请求量大的话,这也是一个不小的开销,如果是像淘宝和京东这种大体量客户群体,光存储用户数据就说一比不小的开销了,并且还需要考虑到一种特殊情况,由于数据需要存储到内存中,然后与cookie做数据比对,这样如果不是单一服务器提供服务,比如A服务器先提供服务,客户端与A建立联系,并且将对应的session存贮起来,当客户端去访问分布式服务器B的时候,就无法建立联系了,因为session是存储在服务器A中的,所以面临分布式服务器系统的时候,cookie和session存在一定的缺陷性,这也为token的产生埋下了伏笔,还要一个需要注意的点就是,cookie伪造的数据不容易被差别出来,cookie和session的验证模式相当于什么,就像某些超市他们可能给每个客户都发放了会员卡,当你购物的时候,验证的决定权是客户,比如我出示会员卡并说我是会员,那么收银员就会把我当成会员帮我打折,但是如果有个人他自己伪造一个会员卡,或者说捡到别人的,然后也说我是会员,收银员依旧会将他当作会员处理,这也是为什么说cookie的安全性低,服务器将返回的信息以明文的形式返回给客户端进行保存,也就是服务端说你是谁你就是谁,而这个“谁”,只要客户端出示了cookie,服务端就验证通过了,但是我们都知道,现在很多验证你是不是会员都需要拿你的会员卡d一下,验证存在才能使用。

这里我将cookie和session验证的缺点总结一下(非全部,我了解内的部分):

①session需要将每一个会话存储会话信息存到内存中,可以理解成账单记账,这样会占用大量的内存,增加服务器的压力

②session有局限性,如果是单服务器不会有问题,因为账单都在总店,但是如果是分布式服务就会面临无法验证的问题

③安全性不高,由于是服务器将cookie发给客户端,客户端只要发送cookie即可通过验证

④app等移动端应用会使得session失效

⑤cookie不允许跨域访问

⑥cookie有大小限制4kb

token是什么呢?

        token是服务端生成的一串字符串,作为客户请求的一个令牌,当第一次登录后,服务器就会生成一个token给客户端,以后的请求带上token就可以无需登录了,其实和cookie非常相似,但是token多了一个验证的步骤,不再是出示即可通过了,相较于cookie,token减轻了服务端的压力,不需要就session这样将大量的会话记录保存起来了,而是通过token,服务器向redis中查询用户的信息,这不解决了cookie缺点①的问题还顺带解决了②session无法处理分布式服务的问题,有了redis,服务器只需要去redis查询用户信息即可,并且token并不限制大小,而cookie只有4k,并且token可以允许跨域的请求,这也是不同与cookie的,也解决了app等移动端应用会使得session失效的问题,由此可见,token在多方面是有优于cookie的,但是之前就说过要结合应用场景,目前cookie和token都有非常常用,但是与登录验证相关似乎大家都对token更有印象了,token除了去redis中查询还有一种JWT的形式,因为频繁的查询redis同样会加强redis的压力,所以JWT相较于查询redis也有他的一定优点,他是将数据交给了游览器存储,下次需要继续请求的时候携带JWT给服务器进行验证就可以了,这样可以避免查询redis这个步骤,在一定程度上降低redis的压力,但是也要根据业务场景,因为对于JWT和token与redis验证的安全性问题我没有做过多的探究。

                                                                    图(5)

token和cookie的安全性对比,为什么token会更安全一点?

        首先token的安全性是高于cookie,之前有提到cookie就相当于服务器为你发放一个通行证,你只要出示通行证即可通过验证,说白了张三拿着服务器发给李四的通行证一样可以访问数据,服务器不会纠结你是谁,cookie是服务器发放给客户端用户的一个通行证,其实token和cookie十分相似,但是不同的是token加入了签名机制,有了签名机制就加强了数据的安全性,那么数字签名的机制是如何保证数据的安全性呢?首先目前比较安全常见的就是JWT,如图(5)的数据结构来完成token传递和认证的,数字签名也是保存在其中,JWT全称是JSon Web Token,数据用Json的形式传输,信息是经过数字签名的,所以信息是值得信任的,JWT一半是一个字符串类似于adb.123ccc.666ad,以.为分隔符,由Header和Payload和Signature三部分组成。

Header:

{

"alg": "HS256", "typ": "JWT"

}

主要有两个属性,typ属性统一写JWT,alg是表示加密使用的算法,这里的HS256就是对称加密,还有一个是RS256是非对称加密,这里埋个伏笔待会详细探讨一下对称与非对称加密(伏笔1)

payload:

这里存放的就是一些类似于cookie的数据,类似于:

有七个默认字段可供选择:

  • iss (issuer):签发人/发行人

  • sub (subject):主题

  • aud (audience):用户

  • exp (expiration time):过期时间

  • nbf (Not Before):生效时间,在此之前是无效的

  • iat (Issued At):签发时间

  • jti (JWT ID):用于标识该 JWT

{

"iss":"zs",

"sub":"123",

"sex":"男" //同样允许写入自定义的字段

}

        值得注意的是,JWT的json对象是采用Base64的方式简单加密的,由于这种加密是可逆,是可以通过反向编码得到原文,所以敏感数据依旧不能放在JWT中

Signature:

        JWT的第三部分就是签名了,这里也是一个重要的部分,我在看到这里的时候产生相对较多的疑问,也去搜索相关知识解惑了,这是是将前面两个部分,header和payload的信息先进行base64加密成字符串的形式再使用头部声明的加密方式,如HS256进行加密后得到的一个数据,可以这么理解,当数据不被篡改的时候,将secret解密后的数据通过base64反向解析后得到的和header和payload是一样的数据,这样也就达到初步验证数据的安全性的一步了,比如客户端将JWT发送个服务器,服务器解密Signature部分发现payload和header与发来的明文payload和header对不上,那就证明信息已经被篡改了,这里的Signature就说是签名,相当于是用户签名了,那么这个过程是如何进行了,是这样的,用户首次登录成功后,会存在一些信息,服务器通过HS256等方式进行加密,将类似于cookie内存储的信息等等验证用户登录成功等信息进行加密存放在一个Signature证书里面,并且替我们署名了,比如易xx,这里有个可以散发的点,我开始就考虑为什么使用HS256这种对称加密的方法,因为对称加密需要对密钥进行妥善保管(不便于传输,待会会详细探讨为什么),后面我才后知后觉,其实这个过程没有用户的参与,用户也就是客户端都没有参与加解密的过程中,是服务器对信息进行了加密解密,也就是说类似于cookie这样验证用户是否登录的信息被服务器加密后,返回给我们了,我们保存下来,下次使用的时候发给服务器,服务器再通过密钥解密确认信息是否被篡改过,如果没有就通过,自始至终都是服务器在做加密和解密验证的工作,密钥也只有服务器知道,由于密钥不需要在客户端和服务器中传输,也就不存在安全性的问题(不考虑传输安全性的情况,对称加密的解密更快,肯定是优于非对称加密的),这也是为什么JWT大多采用HS256,而不是我们认为更安全的RS256(非对称加密),主要就是因为不需要传递密钥,所以业务场景很重要,既然讲到了这些,我就不禁思考什么是数字签名、如何确保数字签名的准确性、以及对称加密和非对称加密区别等待问题,于是我又去详细了解了一下。

                                                                 图(1)

首先什么是数字签名?

首先以RSA数字签名算法为例子:(非对称加密)

        如上图(1)小明为了验证文件属于自己,那么他需要对文件进行数字签名,那么根据RSA数字签名算法会生成公钥和私钥,这里对于公钥和私钥的理解需要注意一下,并不是说这两个都是字面意思钥匙,公私的区分是公钥是发布在互联网中,或者说对外公布,而私钥是个人保存的,比如一个数据可以进行公钥加密,那么拥有私钥的人通过私钥解密就可以获得原文了,同样如果是数据是通过私钥进行加密的,那么公钥解密即可获得原文,结合非对称加密的一个特点就是,私钥加密的前提下,如果只知道公钥是无法获得原文的,所以就有了以下场景:

A公司拥有自己的公钥A和私钥A,同样B公司拥有公钥B和私钥B

(这里我顺带引出对称加密是什么,比如HS256,对称加密其实就是加密和解密用的都是一个钥匙,但是由于加解密用的一个钥匙,密钥的保存和传输就是个问题,如果一旦别人截获密钥的信息就能得到全部数据,同时密钥的保存也是一个问题)

        A公司如果想想B公司发送一段重要隐私信息,那么可以通过B公司的公钥进行加密,将需要传输的数据进行对称加密,将加密的密钥一块发送给B公司,那么只要拥有对应私钥的B公司才能解密获得信息的内容,再通过获取的密钥将对称加密的信息进行解密,这样就保证了信息的安全性,为什么要这么做呢?因为非对称加密的安全性虽然更高,但是加解密相对耗时,所以将信息对称加密,然后再将加密信息和密钥传递给接收方,这样在保证安全性的同时,大大提升了解密的速度(根本是:非对称公钥无法保存,只需要保存后私钥即可,但是加解密过程慢,对称加密,加解密同一密钥,密钥保存难度大,但是加解密过程快,所有优势互补)

                                                                 图(2)

                                                                    图(3)

数字签名是如何保证文件的真实性以及判断我签署的呢?

        同样是以非对称加密为例,通过签名那个问题我们知道了签名主要是由私钥的公钥构成了,由这两个产生了数字签名,那么数字签名是如何保证文件的真实性和是否为我签署的呢?比如我现在是小明,通过RSA非对称签名算法产生了公钥和私钥,如果我需要传递一份能够验证我身份的文件(或者一份重要文件),但是由于明文文件容易被篡改,我会先使用哈希运算将证明文件转换成文件哈希值,不同与base64,哈希运算出的结果是不可逆的,换句话说就是无法通过结果反推出原文,具体为什么我没有特别深究,这里可以举个例子大概说明,不可逆的一个简单示例就是模运算,比如我们可以通过10%3 得出结果1,但是不能通过1反推出10,因为他还可能是4等等,所以哈希运算也是一个与之相似的方式,可能更为复杂,但是原理一样。如图(1)这里我们就得到了文件哈希值,接下来我们通过签名算法生成的私钥对这个文件的哈希值H进行加密,那么就得到了数字签名S,那么公钥、原文件、和数字签名我们是可以明文发送到互联网上,比如这个时候小红需要进行签名的验证,验证小明以及文件真实性,那么他只需要通过公钥对数字签名S进行解密就能得到一个文件哈希值H,同样他可以将文件进行哈希运算成一个文件哈希值H,然后通过两次生成的哈希值H进行比对,如果不一致就说明文件被篡改了,但是也可以说可能是数字签名不是小明的所以比对不通过,但是由于数字签名的机制,数字签名只能由私钥的拥有者产生,所以数字签名一定是由私钥拥有者生成的,或许可以说小明不是文件的拥有者,但是数字签名一定是小明的,但是这里又引出了一个注意点,我们如何确保小明就是私钥的拥有者呢?如图(2)其他人也可以通过数字签名生成公钥和私钥,然后用他的公钥和私钥进行验证,根据流程发现也是可以行得通的,这就好比我拿着张三的入学通知书去上学了,并且签上了张三的名字,那么我依旧可以通过验证,因为你无法判断我是不是张三,同样我无法判断私钥的拥有者是不是小明,但是我们知道一个人在生成私钥的同时也生成了公钥,换而言之就是私钥的拥有者就是公钥的生产者,那么如何判断公钥的生产者是小明呢?由此便诞生了数字证书如图(3),数字证书就是一个权威机构,是证书的颁发机构,他的作用就是证明公钥的生产者是谁也就是私钥的拥有者是谁,那么大家都去一个权威的地方鉴定即可,这样就能避免冒充的情况产生,同样证书颁发结构也有他的一套公钥和私钥,小明将他的信息和公钥发送个CA证书颁发机构,CA在确认无误后会使用他的私钥将小明的身份信息和公钥进行加密并且著名CA认证这类,这样小明再将这份证书放到互联网上就具有了公信力,这相当于学校在给学生颁发毕业证书的时候,会盖上学校的章,这样你拿去企业别人看到这个盖章就愿意相信你的学历了,但是这有衍生出了一个问题,如何确定CA证书不会被伪造呢?如图(4)就好比可能有野鸡大学随便盖章冒充正规学校,那么肯定存在更上层的验证机构,比如国家教育局等等(不太了解可能不合理),但是对于计算机来说,系统中会预先安装一个叫做根证书,根证书保证了那些CA机构是值得被信任的。

                                                                         图(4)

  • 5
    点赞
  • 49
    收藏
    觉得还不错? 一键收藏
  • 4
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值