深度|什么是 JWT ?

Alt

转载自公众号“寻寻觅觅的 Gopher”

Alt

前言

最近在开发一个统一认证服务,涉及到 OIDC 协议,其中授权码模式所颁发的 id_token 使用的是 JWT(JSON Web Token)。

因为这次使用的库的默认签名算法和以往不同,所以特地去翻阅了 JWT 的 RFC 文档( RFC 75191),一番阅读后对 JWT 的核心内容有了更深入的理解。

你也可以在 Authing 官网上了解 JWT Token 的释义及使用,以及在 Authing 系统中验证 token 的方法。什么是 JWT Token?

01

我们最常使用的 JWT

每次提到无状态的 JWT 时,相信都会看到另一种基于 Session 的用户认证方案介绍,这里也不例外,Session 的认证流程通常会像这样:

Alt
这种方案有一些缺点:

  • 需要从内存或数据库里存取 session 数据
  • 扩展性差,对于分布式应用,需要实现 session 数据共享

JWT 正好可以解决这些问题:

Alt
JWT 的用户认证流程颇具优势,将需要使用到的用户数据等信息放入 JWT 中,每次请求都会自动携带,只要保证密钥不泄露,JWT 就无法伪造。

一个简单的 JWT 示例如下:

eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJleHAiOiIyMDIxLTEwLTI0IDAwOjAwOjAwIiwibmFtZSI6InRvZ2V0dG95b3UifQ.XdF46NflSUjnt-adAc6rNZEXI1OD6nxtwGuhz9qkxUA

把上面的 JWT 复制粘贴到 jwt.io2 这个网站中。

Alt
可以看出 JWT 以不同颜色区分,通过两个小数点隔开,分为了三部分:

  • Header(头部):JSON 对象,描述 JWT 的元数据。其中 alg 属性表示签名的算法(algorithm),默认是 HMAC SHA256(写成 HS256);typ 属性表示这个令牌(token)的类型(type),统一写为 JWT。
  • Payload(载荷):JSON 对象,存放实际需要传递的数据,支持自定义字段。
  • Signature(签名):这部分就是 JWT 防篡改的精髓,其值是对前两部分 base64UrlEncode 后使用指定算法签名生成,以默认 HS256 为例,指定一个密钥(secret),就会按照如下公式生成:
HMACSHA256(
 base64UrlEncode(header) + "." + base64UrlEncode(payload),
 secret,
)

到这里,大多数人对 JWT 的认知应该是停留在此了,日常使用也已经足够,但你想更深入了解 JWT 的话,那你就得知道 JOSE 。

02

JOSE 规范

什么是 JOSE,它和 JWT 之间又有什么关系呢?

JOSE 全称 JSON Object Signing and Encryption ( RFC 71653, RFC 75204 ),它定义了一系列的标准,用来规范网络传输过程中使用 JSON 的方式,我们上面一直说的 JWT 其实是 JOSE 体系之一。

Alt
其中 JWT 又可分为 JWS 和 JWE 两种不同的实现,我们大部分日常所使用的,所说的 JWT 其实应该属于 JWS。为什么这么说,请看下文。

03

JWA 和 JWS 以及 JWK

JWA 的全称是 JSON Web Algorithms (RFC 75185) ,字如其名,JOSE 体系中涉及到的所有算法就是它来定义的,比如通用算法有 Base64-URL 和 SHA,签名算法有 HMAC,RSA 和 Elliptic Curve(EC 椭圆曲线)。

本文不会深入到算法原理,只是想让你知道 JWA 是做什么的。上述 JWT 例子中的第一部分 Header 有个 alg 属性,其值是 HS256,也就是 HMAC+SHA256 算法。

JWS 的全称是 JSON Web Signature (RFC 75156) ,它的核心就是签名,保证数据未被篡改,而检查签名的过程就叫做验证。更通俗的理解,就是对应前面提到的 JWT 的第三部分 Signature,所以我才会说我们日常所使用的 JWT 都是 JWS。

通常在客户端-服务端模式中,JWS 使用 JWA 提供的 HS256 算法加上一个密钥即可,这种方式严格依赖密钥,但在分布式场景,可能多个服务都需要验证 JWT,若要在每个服务里面都保存密钥,那么安全性将会大打折扣,要知道,密钥一旦泄露,任何人都可以随意伪造 JWT。

解决办法就是使用非对称加密算法 RSA,RSA 有两把钥匙,一把公钥,一把私钥,可以使用私钥签发(签名分发)JWT ,使用公钥验证 JWT,公钥是所有人都可以获取到的。这样一来,就只有认证服务保存着私钥,进行签发,其他服务只能验证。

如下是一个使用 RS256 (RSA+SHA256) 算法生成的 JWT:

eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCIsImtpZCI6IjF6aXlIVG15M184MDRDOU1jUENHVERmYWJCNThBNENlZG9Wa3VweXdVeU0ifQ.eyJqdGkiOiIzWUJ5eWZ2TDB4b01QNXdwTXVsZ0wiLCJzdWIiOiI2MDE5NDI5NjgwMWRjN2JjMmExYjI3MzUiLCJpYXQiOjE2MTI0NDQ4NzEsImV4cCI6MTYxMzY1NDQ3MSwic2NvcGUiOiJvcGVuaWQgZW1haWwgbWVzc2FnZSIsImlzcyI6Imh0dHBzOi8vc3RlYW0tdGFsay5hdXRoaW5nLmNuL29pZGMiLCJhdWQiOiI2MDE5M2M2MTBmOTExN2U3Y2IwNDkxNTkifQ.cYyZ6buwAjp7DzrYQEhvz5rvUBhkv_s8xzuv2JHgzYx0jbqqsWrA_-gufLTFGmNkZkZwPnF6ktjvPHFT-1iJfWGRruOOMV9QKPhk0S5L2eedtbKJU6XIEkl3F9KbOFwYM53v3E7_VC8RBj5IKqEY0qd4mW36C9VbS695wZlvMYnmXhIopYsd5c83i39fLBF8vEBZE1Rq6tqTQTbHAasR2eUz1LnOqxNp2NNkV2dzlcNIksSDbEGjTNkWceeTWBRtFMi_o9EWaHExdm5574jQ-ei5zE4L7x-zfp9iAe8neuAgTsqXOa6RJswhyn53cW4DwWg_g26lHJZXQvv_RHZRlQ

把它复制到 jwt.io 上面看看

Alt
注意我绿色框选中的地方,里面是一段 JSON,我们把它删掉,看看输入框的提示信息。

Alt
这里提示了,里面是填写公钥格式(通常为 PEM)或者 JWK(我们说过 RSA 算法是使用私钥签发 JWT,公钥进行验证),刚刚我们删掉的是一段 JSON,所以必然不是公钥格式,那是 JWK 吗?

当然是,JWK 的全称是 JSON Web Key (RFC 75177) ,它就是一个 JSON,JWK 就是用 JSON 来表示密钥(JSON 字段因密钥类型而异)。例如刚才删除的 JWK:

{
"e": "AQAB",
"kty": "RSA",
"n": "wVKQLBUqOBiay2dkn9TlbfuaF40_edIKUmdLq6OlvzEMrP4IDzdOk50TMO0nfjJ6v5830_5x0vRg5bzZQeKpHniR0sw7qyoSI6n2eSkSnFt7P-N8gv2KWnwzVs_h9FDdeLOeVOU8k_qzkph3_tmBV7ZZG-4_DEvgvat6ifEC-WzzYqofsIrTiTT7ZFxTqid1q6zrrsmyU2DQH3WdgFiOJVVlN2D0BuZu5X7pGZup_RcWzt_9T6tQsGeU1juSuuUk_9_FVDXNNCTObfKCTKXqjW95ZgAI_xVrMeQC5nXlMh6VEaXfO83oy1j36wUoVUrUnkANhp-dnjTdvJgwN82dGQ"
}

其中 kty 字段是必须的,代表密钥类型,支持 EC 椭圆曲线密钥,RSA 密钥和 oct 对称密钥。

JWK 和公钥格式 Pem 是可以互相转换的:

Alt
我们现在已经知道,验证这个 JWT 是需要公钥或 JWK 的,那你会不会好奇 jwt.io 这个网站是怎么知道 JWK 的呢,为什么一粘贴,就自动将 JWK 填充进去了。

原理其实很简单,而且已经是一种大家都遵循的规范了,就是将 JWK 放在 iss/.well-known/jwks.json 下,其中 iss 就是 Payload 里面的 iss。

Alt
当你在 jwt.io 粘贴下 JWT 的瞬间,jwt.io 会先解析 Header,判断出 JWT 使用的算法(JWA),接着解析出 Payload 的信息,由于这里是 RS256 算法, 所以还会去请求 Payload 里的 iss 下的 .well-known/jwks.json 得到 JWK,从而完成 JWS 的验证。

04

另一种 JWT 的实现:JWE

我们说过,经过 Signature 签名后的 JWT 就是指的 JWS,而 JWS 仅仅是对前两部分签名,保证无法篡改,但是其 Payload(载荷)信息是暴露的(只是作了 base64UrlEncode 处理)。因此,使用 JWS 方式的 Payload 是不适合传递敏感数据的,JWT 的另一种实现 JWE 就是来解决这个问题的。

JWE 全称是 JSON Web Encryption ( RFC 75168) ,JWS 的 Payload 是 Base64Url 的明文,而 JWE 的数据则是经过加密的,它可以使 JWT 更加安全。

JWE 提供了两种方案:共享密钥方案和公钥/私钥方案。

共享密钥方案的工作原理是让各方都知道一个密钥,大家都可以签名验证,这和 JWS 是一致的。

而公钥/私钥方案的工作方式就不同了,在 JWS 中私钥对令牌进行签名,持有公钥的各方只能验证这些令牌;但在 JWE 中,持有私钥的一方是唯一可以解密令牌的一方,公钥持有者可以引入或交换新数据然后重新加密,因此,当使用公钥/私钥方案时,JWS 和 JWE 是互补的。

想要理解这一点的更简单的方法是从生产者和消费者的角度进行思考。

生产者对数据进行签名或加密,消费者可以对其进行验证或解密。对于 JWS,私钥对 JWT 进行签名,公钥用于验证,也就是生产者持有私钥,消费者持有公钥,数据流动只能从私钥持有者到公钥持有者。

相比之下,对于 JWE,公钥是用于加密数据,而私钥用来解密,在这种情况下,数据流动只能从公钥持有者到私钥持有者。如下图所示(来源 JWT Handbook9):

Alt
相比于 JWS 的三个部分,JWE 有五个部分组成(四个小数点隔开)。一个 JWE 示例如下:

eyJhbGciOiJSU0ExXzUiLCJlbmMiOiJBMTI4Q0JDLUhTMjU2In0.
UGhIOguC7IuEvf*NPVaXsGMoLOmwvc1GyqlIKOK1nN94nHPoltGRhWhw7Zx0-kFm1NJn8LE9XShH59*
i8J0PH5ZZyNfGy2xGdULU7sHNF6Gp2vPLgNZ\_\_deLKxGHZ7PcHALUzoOegEI-8E66jX2E4zyJKxYxzZIItRzC5hlRirb6Y5Cl_p-ko3YvkkysZIFNPccxRU7qve1WYPxqbb2Yw8kZqa2rMWI5ng8Otv
zlV7elprCbuPhcCdZ6XDP0_F8rkXds2vE4X-ncOIM8hAYHHi29NX0mcKiRaD0-D-ljQTPcFPgwCp6X-nZZd9OHBv-B3oWh2TbqmScqXMR4gp_A.
AxY8DCtDaGlsbGljb3RoZQ.
KDlTtXchhZTGufMYmOYGS4HffxPSUrfmqCHXaI9wOGY.
9hH0vgRfYgPnAHOd8stkvw
  • Protected Header (受保护的头部) :类似于 JWS 的 Header ,标识加密算法和类型。
  • Encrypted Key(加密密钥) :用于加密密文和其他加密数据的密钥。
  • Initialization Vector (初始化向量) :一些加密算法需要额外的(通常是随机的)数据。
  • Encrypted Data (Ciphertext) (加密的数据) :被加密的数据。
  • Authentication Tag (认证标签) :算法产生的附加数据,可用于验证密文内容不被篡改。

这五个部分的生成,也就是 JWE 的加密过程可以分为 7 个步骤:

  • 根据 Header alg 的声明,生成一定大小的随机数
  • 根据密钥管理方式确定 Content Encryption Key (CEK)
  • 根据密钥管理方式确定 JWE Encrypted Key
  • 计算所选算法所需大小的 Initialization Vector (IV)。如果不需要,可以跳过
  • 如果 Header 声明了 zip ,则压缩明文
  • 使用 CEK、IV 和 Additional Authenticated Data (AAD,额外认证数据) ,通过 Header enc 声明的算法来加密内容,结果为 Ciphertext 和 Authentication Tag
  • 最后按照以下算法构造出 Token:
base64(header) + '.' +
base64(encryptedKey) + '.' + // Steps 2 and 3
base64(initializationVector) + '.' + // Step 4
base64(ciphertext) + '.' + // Step 6
base64(authenticationTag) // Step 6

JWE 相比 JWS 更加安全可靠,但是不够轻量,有点复杂。

05

安全性考虑

总结

今天为大家讲了一些 JWT 不为人知的秘密,总结一下涉及到的知识点:

  • JOSE:规范网络传输过程中使用 JSON 的一系列标准
  • JWT:以 JSON 编码并由 JWS 或 JWE 安全传递的表示形式
  • JWS:签名和验证 Token
  • JWE:加密和解密 Token
  • JWA:定义 JOSE 体系中涉及到的所有算法
  • JWK:用 JSON 来表示密钥

最后,再次附上 JOSE 的体系图,相关的 RFC 均备注在图上了:


希望今天的分享能让你更加了解 JWT!


  1. RFC 7519 ↩︎

  2. jwt.io ↩︎

  3. RFC 7165 ↩︎

  4. RFC 7520 ↩︎

  5. RFC 7518 ↩︎

  6. RFC 7515 ↩︎

  7. RFC 7517 ↩︎

  8. RFC 7516 ↩︎

  9. JWT Handbook ↩︎

相关推荐

洞察|以 AI Agent 身份为中心的下一代 IDaaS 探索,「零信任」原则是否依然有效

若一个 AI 代理被诱骗点击了恶意链接,也应当因其权限受限而无法进一步获取更多内部信息,从而将影响降到最低。

Authing的博客 1139

Authing 正在寻找云原生应用 / Infra 开发者

我们需要云原生应用开发者和云原生基础设施开发者加入我们

Authing的博客 1121

从数据孤岛到信息共享,应用集成网关打造业务新生态

企业通过应用集成网关轻松打通业务隔阂,让应用相互“对话”,快速实现数字化转型和业务发展的持续增长。

Authing的博客 1141

建立统一网络身份认证平台,赋能用户信息安全

随着网络化、数字化、智能化的演进,在深入推进数字经济创新发展、积极培育新兴产业和未来产业的过程中,安全与发展将是永恒的主题,如何确保网络身份安全将是主旋律。

Authing的博客 1524

Authing 2024 年全员大会:坚持原创性、冒险精神和极客精神,突破瓶颈,引领市场

他的话语不仅回顾了过去一年的挑战,也为员工们描绘了一个充满希望的未来。

Authing的博客 1015

构建用户身份基础设施,推动新能源汽车高质量发展

企业的困惑或许不再是“ 0 到 1 阶段的破冰”该如何落实,而是在技术创新和政策支持不断变化的情况下,如何抓住用户并在消费者心中构筑存在感,才是未来竞争中的关键。

Authing的博客 1669

后量子时代,未来密码该何去何从?

在量子信息时代来临之前,如何能够有效抵御量子攻击就成了不得不面对的问题之一。

Authing的博客 1773

当网络安全成为业务增长的重要保障,企业应该如何应对?

企业需要关注的网络安全层面有哪些?企业管理者又应如何应对网络安全问题,准确制定企业安全策略呢?

Authing的博客 1733

七部门重磅发文!未来产业创新该如何发展?

如何确保产业数字安全基础上,加快发展未来产业,支撑推进企业创新发展?

Authing的博客 1026

Authing 身份云入选崔牛会「2024 中国企业服务云图」

提供 OPA(组织过程管理) SaaS ,完善 OPA 计算监控、事件监控、决策监控、决策设计器、代码编写等,覆盖决策计算全生命周期,实现事件驱动的低代码决策引擎和自动化风控引擎。Authing 目前已经服务包括可口可乐、招商银行、三星集团、复星集团、万科集团、海底捞在内的 40000+ 企业和开发者。2024 版云图汇聚了时下国内 3500+ 家数字化领域内优秀的 To B 企业,涵盖技术支撑、数据资产、协同办公、垂直行业等 18 个类别,覆盖万亿级市场,堪称中国企业数字化选型的“宝典”,

Authing的博客 750

管理员分级管控三大模式,提高企业内部管理效率

企业在整个权限管理落地过程中,如何解决这些难题,提高企业内部管理效率?

Authing的博客 2057

零信任网络标准发布,企业如何构建下一代可信任的身份安全体系?

在这样的背景下,企业如何构建下一代可信任的身份安全体系?

Authing的博客 1303

克服数字化三重担忧,从构建身份基础设施开始

如何消除三重担忧,成为企业数字化转型之路的重中之重。

Authing的博客 955

AI 欺诈事件频出,如何重塑身份认证的安全性?

人工智能时代的到来,将不仅仅是科技盛宴,更是信息安全对网络威胁的一次攻坚战。

Authing的博客 1386

教育信创全面加速,如何促进高校信息化建设?

教育数字化转型不是针对一般教育设施的简单更新升级,而是针对整个教育体系的深层次积累,引领教育行业从传统的教育模式向智能化教育迈进,形成适应数字时代的全新教育形态。

Authing的博客 1928

Authing 入选中国信通院《 2023 高质量数字化转型产品及服务全景图》

近日,中国信通院“铸基计划”发布了《高质量数字化转型产品及服务全景图( 2023 )》。Authing 身份云成功入选 IT 维护与运营领域并获得证书。

Authing的博客 704

第三方 Cookie 被禁用?企业该如何实现用户精准运营和管理?

如何收集和利用第一方数据填补第三方 Cookie 的空白,成为许多企业和营销人员需要重新思考的问题。

Authing的博客 1331

从密码认证到 Passkey 无密码,告别传统密码时代

Authing 作为国内领先的身份认证服务商,率先推出 Passkey 无密码认证服务,填补国内密码认证缺陷,降低数据泄漏风险。

Authing的博客 1566

Authing 受邀参加 2023 QCon 全球软件开发大会

Authing 作为身份领域领先企业受邀参加此次大会,与客户深度对话塑造数字化发展未来。

Authing的博客 695

2023 年最先进认证方式上线,Authing 推出 Passkey 无密码认证

密码这一传统身份认证方式已经难以得到可靠的认证保障,随之出现各种新身份认证方式,其中就包括无密码身份认证。

Authing的博客 1554

Authing 分级管理员重磅上线,实现权限超细粒度分级管

为了满足企业内部复杂的组织架构设计需求,企业需要实现“统一管理,分级授权”的权限管理模式,满足企业内部不同角色的需求,提高了整体管理的透明度和可操作性。

Authing的博客 1585

身份自动化工作流,帮助您快速提高工作效率

身份自动化不仅仅简单将手动步骤数字化,更是将企业从传统、低效、甚至过时的工作流程中解放出来,形成数字化引擎,将企业的管理方式从繁琐转变为简洁,从手动迈向自动,为整个组织注入了新的活力。

Authing的博客 1210

从身份治理出发,助力教育行业回归教育本质

在实施国家教育数字化战略行动中,如何利用数字技术优势助力教育治理变革,提升区域、学校教育治理水平成为深化教育改革的一个热点话题。

Authing的博客 1193

身份管理如何提升中小企业生产力?

在此困局中,企业希望依托数字化以求业务增长、人员增效、企业扩张以及产品核心竞争力的稳固。

Authing的博客 1025

先进制造身份治理现状洞察:从手动运维迈向自动化身份治理时代

当前形势下,我国制造业发展之路该如何走?

Authing的博客 1680

Authing CEO 谢扬来信 |我的原则

从忙碌的工作中短暂抽身,有很多感想,不吐不快,借此机会,倾我所有,诉我原则。

Authing的博客 1165

从 RBAC 到 NGAC ,企业如何实现自动化权限管理?

谁具有特定数据的访问权限?您的企业是否实现了对员工权限的有效管理?

Authing的博客 2205

如何为您的企业选择合适的多因素认证?

如何评估企业的 MFA 需求,如何选择合适的 MFA 解决方案?这些都成为企业在如今安全环境下需要思考的问题。

Authing的博客 1266

放弃无谓的「技术氛围」幻想,准备战斗

资本绝不会做亏本买卖,一家公司在市场中的一切动作都以盈利为目的。

Authing的博客 225

Authing 入选《 2023 年央国企信创应用与实践研究报告》优秀服务商

Authing 身份云作为国内唯一事件驱动云原生身份平台入选《 2023 年央国企信创应用与实践研究报告》优秀服务商。

Authing的博客 728
上一篇: 集简云 x Authing,助力网校打通用户身份管理屏障
下一篇: 程序员表白代码
Authing
Authing 企业官方账号 企业官方账号
博客等级 码龄6年 863粉丝 304原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值