JWT、JWE、JWS 、JWK 都是什么鬼?还傻傻分不清?
《一线大厂Java面试题解析+核心总结学习笔记+最新讲解视频+实战项目源码》 ,点击传送门,即可获取!
一个JWT,应该是如下形式的:
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.
eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiYWRtaW4iOnRydWV9.
TJVA95OrM7E2cBab30RMHrHDcEfxjoYZgeFONFh7HgQ
这些东西看上很凌乱,但是非常紧凑,并且是可打印的主要用于验证签名的真实性。
JWT 解决什么问题?
JWT的主要目的是在服务端和客户端之间以安全的方式来转移声明。主要的应用场景如下所示:
授权 Authorization // 注意这两个单词的区别;
JWT 的一些名词解释
JWE:Encrypted JWT部分payload经过加密的jwt;目前加密payload的操作不是很普及;
JWKset:JWT key set在非对称加密中,需要的是密钥对而非单独的密钥,在后文中会阐释;
nonsecure JWT:当头部的签名算法被设定为none的时候,该JWT是不安全的;因为签名的部分空缺,所有人都可以修改。
JWT的组成
signture:拥有该部分的JWT被称为JWS,也就是签了名的JWS;没有该部分的JWT被称为nonsecure JWT 也就是不安全的JWT,此时header中声明的签名算法为none。
三个部分用·分割。形如 xxxxx.yyyyy.zzzzz的样式。
JWT header
{
“typ”: “JWT”,
“alg”: “none”,
“jti”: “4f1g23a12aa”
}
头通常由两部分组成:令牌的类型,即JWT,以及正在使用的散列算法,例如HMAC SHA256或RSA。
当然,还有两个可选的部分,一个是jti,也就是JWT ID,代表了正在使用JWT的编号,这个编号在对应服务端应当唯一。当然,jti也可以放在payload中。
base64UrlEncode(header)
eyJ0eXAiOiJKV1QiLCJhbGciOiJub25lIiwianRpIjoiNGYxZzIzYTEyYWEifQ
{
“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 ;每个声明,都有各自的字段。
sub 【subject】该JWT所面向的用户,用于处理特定应用,不是常用的字段
exp 【expiration】 该jwt销毁的时间;unix时间戳
nbf 【not before】 该jwt的使用时间不能早于该时间;unix时间戳
iat 【issued at】 该jwt的发布时间;unix 时间戳
Public Claims 这些可以由使用JWT的那些标准化组织根据需要定义,应当参考文档IANA JSON Web Token Registry。
Private Claims 这些是为在同意使用它们的各方之间共享信息而创建的自定义声明,既不是注册声明也不是公开声明。上面的payload中,没有public claims只有private claims。最新面试题整理好了,点击Java面试库小程序在线刷题。
base64UrlEncode(payload)
eyJpc3MiOiJodHRwOi8vc2hhb2Jhb2Jhb2VyLmNuIiwiYXVkIjoiaHR0cDovL3NoYW9iYW9iYW9lci5jbi93ZWJ0ZXN0L2p3dF9hdXRoLyIsImp0aSI6IjRmMWcyM2ExMmFhIiwiaWF0IjoxNTM0MDcwNTQ3LCJuYmYiOjE1MzQwNzA2MDcsImV4cCI6MTUzNDA3NDE0NywidWlkIjoxLCJkYXRhIjp7InVuYW1lIjoic2hhb2JhbyIsInVFbWFpbCI6InNoYW9iYW9iYW9lckAxMjYuY29tIiwidUlEIjoiMHhBMCIsInVHcm91cCI6Imd1ZXN0In19
当然,这也是有解决方案的,那就是加密payload。在之后会说到。
JWS
JWS 的概念
JWS ,也就是JWT Signature,其结构就是在之前nonsecure JWT的基础上,在头部声明签名算法,并在最后添加上签名。创建签名,是保证jwt不能被他人随意篡改。
为了完成签名,除了用到header信息和payload信息外,还需要算法的密钥,也就是secret。当利用非对称加密方法的时候,这里的secret为私钥。
为了方便后文的展开,我们把JWT的密钥或者密钥对,统一称为JSON Web Key,也就是JWK。
RSASSA || ECDSA || HMACSHA256(
base64UrlEncode(header) + “.” +
base64UrlEncode(payload),
secret)
GQPGEpixjPZSZ7CmqXB-KIGNzNl4Y86d3XOaRsfiXmQ
上面这个是用 HMAC SHA256生成的
对称加密HMAC【哈希消息验证码】:HS256/HS384/HS512
非对称加密RSASSA【RSA签名算法】(RS256/RS384/RS512)
ECDSA【椭圆曲线数据签名算法】(ES256/ES384/ES512)
最后将签名与之前的两段内容用.连接,就可以得到经过签名的JWT,也就是JWS。
eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiIsImp0aSI6IjRmMWcyM2ExMmFhIn0.eyJpc3MiOiJodHRwOi8vc2hhb2Jhb2Jhb2VyLmNuIiwiYXVkIjoiaHR0cDovL3NoYW9iYW9iYW9lci5jbi93ZWJ0ZXN0L2p3dF9hdXRoLyIsImp0aSI6IjRmMWcyM2ExMmFhIiwiaWF0IjoxNTM0MDcwNTQ3LCJuYmYiOjE1MzQwNzA2MDcsImV4cCI6MTUzNDA3NDE0NywidWlkIjoxLCJkYXRhIjp7InVuYW1lIjoic2hhb2JhbyIsInVFbWFpbCI6InNoYW9iYW9iYW9lckAxMjYuY29tIiwidUlEIjoiMHhBMCIsInVHcm91cCI6Imd1ZXN0In19.GQPGEpixjPZSZ7CmqXB-KIGNzNl4Y86d3XOaRsfiXmQ
JWS 的额外头部声明
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字段,这是一个数组,代表着多个签名。
点击关注公众号,Java干货****及时送达
每个签名的结构如下:
protected:之前的头部声明,利用b64uri加密;
header:JWS的额外声明,这段内容不会放在签名之中,无需验证;
signature:也就是对当前header+payload的签名。
JWE
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 Encryption
Key Wrapping
Direct Key Agreement
Key Agreement with Key Wrapping
Direct Encryption
并不是所有的JWA都能够支持这五种密钥管理管理模式,也并非每种密钥管理模式之间都可以相互转换。可以参考Spomky-Labs/jose中给出的表格:
https://github.com/Spomky-Labs/jose/blob/master/doc/operation/Encrypt.md
至于各个密钥管理模式的细节,还请看JWT的官方手册,解释起来较为复杂。另外,Java系列面试题和答案全部整理好了,微信搜索Java技术栈,在后台发送:面试,可以在线阅读。
JWE Header
就好像是JWS的头部一样。JWE的头部也有着自己规定的额外声明字段,如下所示:
type:一般是 jwt
alg:算法名称,和JWS相同,该算法用于加密稍后用于加密内容的实际密钥
enc:算法名称,用上一步生成的密钥加密内容的算法。
更多:Java进阶核心知识集
包含:JVM,JAVA集合,网络,JAVA多线程并发,JAVA基础,Spring原理,微服务,Zookeeper,Kafka,RabbitMQ,Hbase,MongoDB,Cassandra,设计模式,负载均衡,数据库,一致性哈希,JAVA算法,数据结构,加密算法,分布式缓存等等

高效学习视频
《一线大厂Java面试题解析+核心总结学习笔记+最新讲解视频+实战项目源码》 ,点击传送门,即可获取!
master/doc/operation/Encrypt.md
至于各个密钥管理模式的细节,还请看JWT的官方手册,解释起来较为复杂。另外,Java系列面试题和答案全部整理好了,微信搜索Java技术栈,在后台发送:面试,可以在线阅读。
JWE Header
就好像是JWS的头部一样。JWE的头部也有着自己规定的额外声明字段,如下所示:
type:一般是 jwt
alg:算法名称,和JWS相同,该算法用于加密稍后用于加密内容的实际密钥
enc:算法名称,用上一步生成的密钥加密内容的算法。
更多:Java进阶核心知识集
包含:JVM,JAVA集合,网络,JAVA多线程并发,JAVA基础,Spring原理,微服务,Zookeeper,Kafka,RabbitMQ,Hbase,MongoDB,Cassandra,设计模式,负载均衡,数据库,一致性哈希,JAVA算法,数据结构,加密算法,分布式缓存等等
[外链图片转存中…(img-pdqRaJQA-1714699878342)]
高效学习视频
《一线大厂Java面试题解析+核心总结学习笔记+最新讲解视频+实战项目源码》 ,点击传送门,即可获取!
