一个JWT,应该是如下形式的:eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.
eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiYWRtaW4iOnRydWV9.
TJVA95OrM7E2cBab30RMHrHDcEfxjoYZgeFONFh7HgQ
这些东西看上很凌乱,但是非常紧凑,并且是可打印的主要用于验证签名的真实性。JWT 解决什么问题?JWT的主要目的是在服务端和客户端之间以安全的方式来转移声明。主要的应用场景如下所示:1.认证 Authentication;2.授权 Authorization // 注意这两个单词的区别;3.联合识别;4.客户端会话(无状态的会话);5.客户端机密。JWT 的一些名词解释1.JWS:Signed JWT签名过的jwt2.JWE:Encrypted JWT部分payload经过加密的jwt;目前加密payload的操作不是很普及;3.JWK:JWT的密钥,也就是我们常说的scret;4.JWKset:JWT key set在非对称加密中,需要的是密钥对而非单独的密钥,在后文中会阐释;5.JWA:当前JWT所用到的密码学算法;6.nonsecure JWT:当头部的签名算法被设定为none的时候,该JWT是不安全的;因为签名的部分空缺,所有人都可以修改。0x01 JWT的组成一个通常你看到的jwt,由以下三部分组成,它们分别是:1.header:主要声明了JWT的签名算法;2.payload:主要承载了各种声明并传递明文数据;3.signture:拥有该部分的JWT被称为JWS,也就是签了名的JWS;没有该部分的JWT被称为nonsecure JWT 也就是不安全的JWT,此时header中声明的签名算法为none。三个部分用·分割。形如 xxxxx.yyyyy.zzzzz的样式。JWT header{
“typ”: “JWT”,
“alg”: “none”,
“jti”: “4f1g23a12aa”
}
jwt header 的组成头通常由两部分组成:令牌的类型,即JWT,以及正在使用的散列算法,例如HMAC SHA256或RSA。当然,还有两个可选的部分,一个是jti,也就是JWT ID,代表了正在使用JWT的编号,这个编号在对应服务端应当唯一。当然,jti也可以放在payload中。另一个是cty,也就是content type。这个比较少见,当payload为任意数据的时候,这个头无需设置,但是当内容也带有jwt的时候。也就是嵌套JWT的时候,这个值必须设定为jwt。这种情况比较少见。jwt header 的加密算法加密的方式如下:base64UrlEncode(header)

eyJ0eXAiOiJKV1QiLCJhbGciOiJub25lIiwianRpIjoiNGYxZzIzYTEyYWEifQ
JWT payload{
“iss”: “http://shaobaobaoer.cn”,
“aud”: “http://shaobaobaoer.cn/webtest/jwt_auth/”,
“jti”: “4f1g23a12aa”,
“iat”: 1534070547,
“nbf”: 1534070607,
“exp”: 1534074147,
“uid”: 1,
“data”: {
“uname”: “shaobao”,
“uEmail”: “shaobaobaoer@126.com”,
“uID”: “0xA0”,
“uGroup”: “guest”
}
}
jwt payload的组成payload通常由三个部分组成,分别是 Registered Claims ; Public Claims ; Private Claims ;每个声明,都有各自的字段。Registered Claimsiss 【issuer】发布者的url地址sub 【subject】该JWT所面向的用户,用于处理特定应用,不是常用的字段aud 【audience】接受者的url地址exp 【expiration】 该jwt销毁的时间;unix时间戳nbf 【not before】 该jwt的使用时间不能早于该时间;unix时间戳iat 【issued at】 该jwt的发布时间;unix 时间戳jti 【JWT ID】 该jwt的唯一ID编号Public Claims这些可以由使用JWT的那些标准化组织根据需要定义,应当参考文档IANA JSON Web Token Registry。Private Claims这些是为在同意使用它们的各方之间共享信息而创建的自定义声明,既不是注册声明也不是公开声明。上面的payload中,没有public claims只有private claims。jwt payload 的加密算法加密的方式如下:base64UrlEncode(payload)

eyJpc3MiOiJodHRwOi8vc2hhb2Jhb2Jhb2VyLmNuIiwiYXVkIjoiaHR0cDovL3NoYW9iYW9iYW9lci5jbi93ZWJ0ZXN0L2p3dF9hdXRoLyIsImp0aSI6IjRmMWcyM2ExMmFhIiwiaWF0IjoxNTM0MDcwNTQ3LCJuYmYiOjE1MzQwNzA2MDcsImV4cCI6MTUzNDA3NDE0NywidWlkIjoxLCJkYXRhIjp7InVuYW1lIjoic2hhb2JhbyIsInVFbWFpbCI6InNoYW9iYW9iYW9lckAxMjYuY29tIiwidUlEIjoiMHhBMCIsInVHcm91cCI6Imd1ZXN0In19
暴露的信息所以,在JWT中,不应该在载荷里面加入任何敏感的数据。在上面的例子中,我们传输的是用户的User ID,邮箱等。这个值实际上不是什么敏感内容,一般情况下被知道也是安全的。但是像密码这样的内容就不能被放在JWT中了。如果将用户的密码放在了JWT中,那么怀有恶意的第三方通过Base64解码就能很快地知道你的密码了。当然,这也是有解决方案的,那就是加密payload。在之后会说到。0x02 JWS 的概念JWS 的结构JWS ,也就是JWT Signature,其结构就是在之前nonsecure JWT的基础上,在头部声明签名算法,并在最后添加上签名。创建签名,是保证jwt不能被他人随意篡改。为了完成签名,除了用到header信息和payload信息外,还需要算法的密钥,也就是secret。当利用非对称加密方法的时候,这里的secret为私钥。为了方便后文的展开,我们把JWT的密钥或者密钥对,统一称为JSON Web Key,也就是JWK。jwt signature 的签名算法RSASSA || ECDSA || HMACSHA256(
base64UrlEncode(header) + “.” +
base64UrlEncode(payload),
secret)

GQPGEpixjPZSZ7CmqXB-KIGNzNl4Y86d3XOaRsfiXmQ

上面这个是用 HMAC SHA256生成的

到目前为止,jwt的签名算法有三种。对称加密HMAC【哈希消息验证码】:HS256/HS384/HS512非对称加密RSASSA【RSA签名算法】(RS256/RS384/RS512)和ECDSA【椭圆曲线数据签名算法】(ES256/ES384/ES512)最后将签名与之前的两段内容用.连接,就可以得到经过签名的JWT,也就是JWS。eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiIsImp0aSI6IjRmMWcyM2ExMmFhIn0.eyJpc3MiOiJodHRwOi8vc2hhb2Jhb2Jhb2VyLmNuIiwiYXVkIjoiaHR0cDovL3NoYW9iYW9iYW9lci5jbi93ZWJ0ZXN0L2p3dF9hdXRoLyIsImp0aSI6IjRmMWcyM2ExMmFhIiwiaWF0IjoxNTM0MDcwNTQ3LCJuYmYiOjE1MzQwNzA2MDcsImV4cCI6MTUzNDA3NDE0NywidWlkIjoxLCJkYXRhIjp7InVuYW1lIjoic2hhb2JhbyIsInVFbWFpbCI6InNoYW9iYW9iYW9lckAxMjYuY29tIiwidUlEIjoiMHhBMCIsInVHcm91cCI6Imd1ZXN0In19.GQPGEpixjPZSZ7CmqXB-KIGNzNl4Y86d3XOaRsfiXmQ
当验证签名的时候,利用公钥或者密钥来解密Sign,和 base64UrlEncode(header) + “.” + base64UrlEncode(payload) 的内容完全一样的时候,表示验证通过。JWS 的额外头部声明如果对于CA有些概念的话,这些内容会比较好理解一些。为了确保服务器的密钥对可靠有效,同时也方便第三方CA机构来签署JWT而非本机服务器签署JWT,对于JWS的头部,可以有额外的声明,以下声明是可选的,具体取决于JWS的使用方式。如下所示:jku: 发送JWK的地址;最好用HTTPS来传输jwk: 就是之前说的JWKkid: jwk的ID编号x5u: 指向一组X509公共证书的URLx5c: X509证书链x5t:X509证书的SHA-1指纹x5t#S256: X509证书的SHA-256指纹typ: 在原本未加密的JWT的基础上增加了 JOSE 和 JOSE+ JSON。JOSE序列化后文会说及。适用于JOSE标头的对象与此JWT混合的情况。crit: 字符串数组,包含声明的名称,用作实现定义的扩展,必须由 this->JWT的解析器处理。不常见。多重验证与JWS序列化当需要多重签名或者JOSE表头的对象与JWS混合的时候,往往需要用到JWS的序列化。JWS的序列化结构如下所示:{
“payload”: “eyJpc3MiOiJqb2UiLA0KICJleHAiOjEzMDA4MTkzODAsDQogImh0dHA6Ly9leGFtcGxlLmNvbS9pc19yb290Ijp0cnVlfQ”,
“signatures”:
[
{
“protected”: “eyJhbGciOiJSUzI1NiJ9”,
“header”: { “kid”: “2010-12-29” },
“signature”:“signature1”
},
{
“protected”: “eyJhbGciOiJSUzI1NiJ9”,
“header”: { “kid”: “e9bc097a-ce51-4036-9562-d2ade882db0d” },
“signature”:“signature2”
},

]
}
结构很容易理解。首先是payload字段,这个不用多讲,之后是signatures字段,这是一个数组,代表着多个签名。每个签名的结构如下:protected:之前的头部声明,利用b64uri加密;header:JWS的额外声明,这段内容不会放在签名之中,无需验证;signature:也就是对当前header+payload的签名。0x03 JWE 相关概念JWE是一个很新的概念,总之,除了jwt的官方手册外,很少有网站或者博客会介绍这个东西。也并非所有的库都支持JWE。这里记录一下自己看官方手册后理解下来的东西。JWS是去验证数据的,而JWE(JSON Web Encryption)是保护数据不被第三方的人看到的。通过JWE,JWT变得更加安全。JWE和JWS的公钥私钥方案不相同,JWS中,私钥持有者加密令牌,公钥持有者验证令牌。而JWE中,私钥一方应该是唯一可以解密令牌的一方。在JWE中,公钥持有可以将新的数据放入JWT中,但是JWS中,公钥持有者只能验证数据,不能引入新的数据。因此,对于公钥/私钥的方案而言,JWS和JWE是互补的。JWE 的构成一个JWE,应该是如下形式的:eyJhbGciOiJSU0ExXzUiLCJlbmMiOiJBMTI4Q0JDLUhTMjU2In0.
UGhIOguC7IuEvf_NPVaXsGMoLOmwvc1GyqlIKOK1nN94nHPoltGRhWhw7Zx0-kFm1NJn8LE9XShH59_
i8J0PH5ZZyNfGy2xGdULU7sHNF6Gp2vPLgNZ__deLKxGHZ7PcHALUzoOegEI-8E66jX2E4zyJKxYxzZIItRzC5hlRirb6Y5Cl_p-ko3YvkkysZIFNPccxRU7qve1WYPxqbb2Yw8kZqa2rMWI5ng8Otv
zlV7elprCbuPhcCdZ6XDP0_F8rkXds2vE4X-ncOIM8hAYHHi29NX0mcKiRaD0-D-ljQTPcFPgwCp6X-nZZd9OHBv-B3oWh2TbqmScqXMR4gp_A.
AxY8DCtDaGlsbGljb3RoZQ.
KDlTtXchhZTGufMYmOYGS4HffxPSUrfmqCHXaI9wOGY.
9hH0vgRfYgPnAHOd8stkvw
如你所见JWE一共有五个部分,分别是:The protected header,类似于JWS的头部;The encrypted key,用于加密密文和其他加密数据的对称密钥;The initialization vector,初始IV值,有些加密方式需要额外的或者随机的数据;The encrypted data (cipher text),密文数据;The authentication tag,由算法产生的附加数据,来防止密文被篡改。JWE 密钥加密算法一般来说,JWE需要对密钥进行加密,这就意味着同一个JWT中至少有两种加密算法在起作用。但是并非将密钥拿来就能用,我们需要对密钥进行加密后,利用JWK密钥管理模式来导出这些密钥。JWK的管理模式有以下五种,分别是:Key EncryptionKey WrappingDirect Key AgreementKey Agreement with Key WrappingDirect Encryption并不是所有的JWA都能够支持这五种密钥管理管理模式,也并非每种密钥管理模式之间都可以相互转换。可以参考Spomky-Labs/jose中给出的表格至于各个密钥管理模式的细节,还请看JWT的官方手册,解释起来较为复杂。JWE Header就好像是JWS的头部一样。JWE的头部也有着自己规定的额外声明字段,如下所示:type:一般是 jwtalg:算法名称,和JWS相同,该算法用于加密稍后用于加密内容的实际密钥enc:算法名称,用上一步生成的密钥加密内容的算法。zip:加密前压缩数据的算法。该参数可选,如果不存在则不执行压缩,通常的值为 DEF,也就是deflate算法jku/jkw/kid/x5u/x5c/x5t/x5t#S256/typ/cty/crit:和JWS额额外声明一样。JWE 的加密过程步骤2和步骤3,更具不同的密钥管理模式,应该有不同的处理方式。在此只罗列一些通常情况。之前谈及,JWE一共有五个部分。现在来详细说一下加密的过程:1.根据头部alg的声明,生成一定大小的随机数;2.根据密钥管理模式确定加密密钥;3.根据密钥管理模式确定JWE加密密钥,得到CEK;4.计算初始IV,如果不需要,跳过此步骤;5.如果ZIP头申明了,则压缩明文;6.使用CEK,IV和附加认证数据,通过enc头声明的算法来加密内容,结果为加密数据和认证标记;7.压缩内容,返回token。base64(header) + ‘.’ +
base64(encryptedKey) + ‘.’ + // Steps 2 and 3
base64(initializationVector) + ‘.’ + // Step 4
base64(ciphertext) + ‘.’ + // Step 6
base64(authenticationTag) // Step 6
多重验证与JWE序列化和JWS类似,JWE也定义了紧凑的序列化格式,用来完成多种形式的加密。大致格式如下所示:{
“protected”: “eyJlbmMiOiJBMTI4Q0JDLUhTMjU2In0”,
“unprotected”: { “jku”:“https://server.example.com/keys.jwks” },
“recipients”:[
{
“header”: { “alg”:“RSA1_5”,“kid”:“2011-04-29” },
“encrypted_key”:
“UGhIOguC7Iu…cqXMR4gp_A”
},
{
“header”: { “alg”:“A128KW”,“kid”:“7” },
“encrypted_key”: “6KB707dM9YTIgH…9locizkDTHzBC2IlrT1oOQ”
}
],
“iv”: “AxY8DCtDaGlsbGljb3RoZQ”,
“ciphertext”: “KDlTtXchhZTGufMYmOYGS4HffxPSUrfmqCHXaI9wOGY”,
“tag”: “Mz-VPPyU4RlcuYv1IwIvzw”
}
结构很容易理解,如下所示:protected:之前的头部声明,利用b64uri加密;unprotected:一般放JWS的额外声明,这段内容不会被b64加密;iv:64加密后的iv参数;add:额外认证数据;ciphertext:b64加密后的加密数据;recipients:b64加密后的认证标志-加密链,这是一个数组,每个数组中包含了两个信息;header:主要是声明当前密钥的算法;encrypted_key:JWE加密密钥。0x04 JWT 的工作原理这里通过juice shop来说下jwt是如何工作的。在身份验证中,当用户使用其凭据成功登录时,将返回JSON Web令牌。如下所示:往此时,返回了jwt的令牌。每当用户想要访问受保护的路由或资源时,用户将使用承载【bearer】模式发送JWT,通常在Authorization标头中。标题的内容应如下所示:Authorization: Bearer
随后,服务器会取出token中的内容,来返回对应的内容。须知,这个token不一定会储存在cookie中,如果存在cookie中的话,需要设置为http-only,防止XSS。另外,还可以放在别的地方,比如localStorage、sessionStorage。如果使用vue的话,还可以存在vuex里面。另外,如果在如Authorization: Bearer中发送令牌,则跨域资源共享(CORS)将不会成为问题,因为它不使用cookie。此时,去访问认证页面,请求头如下所示,如预期所见,是利用Authorization:Bearer的请求头去访问的。ECDSA|RSASSA or HMAC ? 应该选用哪个?之前看JWT的时候看到论坛里的一个话题,觉得很有意思,用自己的理解来说一下https://stackoverflow.com/questions/38588319/understanding-rsa-signing-for-jwt。首先,我们必须明确一点,无论用的是 HMAC,RSASSA,ECDSA;密钥,公钥,私钥都不会发送给客户端,仅仅会保留在服务端上。对称的算法HMAC适用于单点登录,一对一的场景中。速度很快。但是面对一对多的情况,比如一个APP中的不同服务模块,需要JWT登录的时候,主服务端【APP】拥有一个私钥来完成签名即可,而用户带着JWT在访问不同服务模块【副服务端】的时候,副服务端只要用公钥来验证签名就可以了。从一定程度上也减少了主服务端的压力。当然,还有一种情况就是不同成员进行开发的时候,大家可以用统一的私钥来完成签名,然后用各自的公钥去完成对JWT的认证,也是一种非常好的开发手段。因此,构建一个没有多个小型“微服务应用程序”的应用程序,并且开发人员只有一组的,选择HMAC来签名即可。其他情况下,尽量选择RSA。

JWT最全知识点-动力节点相关推荐

  1. 超全面的Java全套教程分享_动力节点完整版视频教程

    各种各样的编程语言不断崛起,但唯有Java是牢牢占据着老大的位置,目前几乎90%以上的大中型互联网应用系统在服务器端开发首选Java. 因此,也是吸引了不少年轻人投入到Java的学习之中. 但不得不说 ...

  2. 史上最全SpringBoot学习笔记-动力节点王鹤(2021最新版)

    SpringBoot 资料官方下载地址 动力节点springboot资料 视频观看地址 https://www.bilibili.com/video/BV1XQ4y1m7ex 第一章 JavaConf ...

  3. SpringCloud重要知识点总结,动力节点Spring Cloud入门到精通学习教程

    SpringCloud的教程很多小伙伴一定都看过,那么,在SpringCloud学习中需要掌握哪些知识点?今天来给大家梳理下. 什么是分布式? 不同模块部署在不同服务器上 作用:分布式解决网站高并发带 ...

  4. Maven学习笔记,动力节点maven教程随堂笔记(史上最全)

    Maven笔记 这篇笔记的学习视频来自b站动力节点 https://www.bilibili.com/video/BV1dp4y1Q7Hf 笔记中的源码下载地址 动力节点maven资料 第一部分 1. ...

  5. 动力节点——Java学习路线图

    史上最全最细Java学习路线图-动力节点官方出品 2019年最新Java学习路线图, 路线图的宗旨就是分享,专业,便利,让喜爱Java的人,都能平等的学习.从今天起不要再找借口,不要再说想学Java却 ...

  6. 动力节点『lol版』Java学习路线图(五)Java框架阶段

    五.框架之路-丛林沙漠巨神峰 框架技术 送君千里终须一别,拜别了厄运小姐和格雷福斯的盛情挽留,在目送了崔斯特开大消失后,ez在哈雷尔港驻足了片刻便启程前往以绪奥肯.他摸了摸纳袋(空间口袋),里面是菲兹 ...

  7. 2022全新Java学习路线图动力节点(五)框架之路

    五.框架之路-丛林沙漠巨神峰 框架技术 送君千里终须一别,拜别了厄运小姐和格雷福斯的盛情挽留,在目送了崔斯特开大消失后,ez在哈雷尔港驻足了片刻便启程前往以绪奥肯.他摸了摸纳袋(空间口袋),里面是菲兹 ...

  8. 动力节点最新SSM框架项目「米米商城」实战教程分享

    今天分享的是动力节点最新的SSM框架项目-米米商城,这个项目的主要目的是使大家更深层的了解IT企业的文化和岗位需求.模拟企业的工作场景,分享研制成果,增加大家对今后工作岗位及计算机应用开发对客观世界影 ...

  9. Python后端转JAVA最快多久_【动力节点】老杜支招:Java小白学习入门攻略,涵盖学习路线...

    动力节点在B站的直播相当好,相当受欢迎,教学总监亲自解惑.零基础学Java的同学确实把思路打开不少. 回顾:11月14日晚8:00,杜老师在动力节点B站大咖直播间,首次开播与粉丝面基,本场直播不吹,不 ...

最新文章

  1. bootstrap Table API和一些简单使用方法
  2. linux 系统基础知识 - fdisk命令
  3. HTTP/2笔记之连接建立
  4. hdu 1753大小数相加
  5. react draft api 简介
  6. 以KNN为例用sklearn进行数据分析和预测
  7. 请简要说明一下CyclicBarrier和CountDownLatch的区别?
  8. 什么是 SAP Core Data Service Annotation Propagation
  9. GDB and core
  10. 使用composer下载依赖包下载失败的解决方法
  11. 12 快件文档“更新终止”从作者“xxx”收到
  12. URL加载系统之三:NSURLConnection
  13. sql between包括两端吗_技术分享:T-SQL 之语法艺术(一)
  14. 计算机设计思想 —— 类比、建模与隐喻(同构)
  15. Linux下tar压缩解压命令详解
  16. HTC G14解锁S-OFF、刷机、获取ROOT权限
  17. 记第一次阿里数据研发工程师面试
  18. 光电二极管的工作原理
  19. 机器视觉OpenCV-sobel、robert、gauss算子边缘检测
  20. 利用js完成根据excel填充网页表单

热门文章

  1. 大疆A型板使用经验分享(八)——FreeRTOS操作系统的使用
  2. 学Python需要安装什么软件?Python软件工具大全
  3. 超火的口红机源码分享
  4. 超全的iOS面试题汇总
  5. java里人带狗散步,不想带狗狗出门散步,告诉你5个遛狗的好处,不仅仅只有狗狗受益...
  6. 计算机的一级基础知识
  7. R语言数据分析笔记——t检验(含正态性检验和方差齐性检验在SPSS和R语言中的操作t检验(单样本、双独立样本、配对样本)在Excel、SPSS、R语言中的操作)
  8. Java SE - 10 - 多线程
  9. Git 教程 - Git 基本用法
  10. 算法创作|随机出10道题并计算正确率问题解决方法