你只知道JWT,那JWE、JWS、JWK、JWA呢?

目录
文章目录隐藏
  1. JOSE 简介
  2. 小结

移动端兴起和 OAuth2 的流行导致 JWT 这几年火得一塌糊涂。今天要介绍另一个规范集 JOSE,全称 Javascript Object Signing and Encryption,它和 JWT 有莫大的关系。

JOSE 简介

JOSE 是一个 Javascript 对象签名和加密协议,目的是提供一种在各个通讯方之间安全传输声明( claims,例如授权信息 )的方法,它特意构建在 JSON 和 BASE64 之上,以便在 Web 应用程序中轻松使用。目前该规范还在不断地发展,我们常用的包含以下几个由 RFC 文档定义的概念:

JOSE 规范集
JOSE 规范集

JWT 就可以用 JWS 或 JWE 表示,稍后我会详细介绍这一方面的知识。

JWS

JSON Web 签名,基于 JSON 数据结构、使用数字签名技术或者消息认证码技术保护的内容(MAC)都可以称为 JWS。该规范使用的密码算法和标识符在另一个规范 JWA 中定义。规则是比较多的参见RFC7515,这里我们通过序列化来感受一下即可。

JWS 序列化

JWS 的序列化分为 JWS Compact Serialization 和 JWS JSON Serialization 两种。

JWS Compact Serialization

该序列化表示为一种 URL 安全的、紧凑的字符串。格式为:

BASE64URL(UTF8(JWS Protected Header)) || '.' ||
      BASE64URL(JWS Payload) || '.' ||
      BASE64URL(JWS Signature)

例如:

eyJhbGciOiJFUzI1NiJ9.eyJpc3MiOiJqb2UiLA0KICJleHAiOjEzMDA4MTkzODAsDQogImh0dHA6Ly9leGFtcGxlLmNvbS9pc19yb290Ijp0cnVlfQ.DtEhU3ljbEg8L38VWAfUAqOyKAM6-Xx-F4GawxaepmXFCgfTjDxw5djxLa8ISlSApmWQxfKTUJqPP3-Kg6NU1Q

JWT 通常就是这种格式。

JWS JSON Serialization

该序列化表示为一个 JSON 对象,有两种格式。一般格式为:

{
      "payload":"<payload contents>",
      "signatures":[
       {"protected":"<integrity-protected header 1 contents>",
        "header":"<non-integrity-protected header 1 contents>“,
        "signature":"<signature 1 contents>"},
       {"protected":"<integrity-protected header N contents>",
        "header":"<non-integrity-protected header N contents>",
        "signature":"<signature N contents>"}]
}

平铺格式为:

{
      "payload":"<payload contents>",
      "protected":"<integrity-protected header contents>",
      "header":"<non-integrity-protected header contents>",
      "signature":"<signature contents>"
}

举个一般格式的例子:

{
      "payload":
       "eyJpc3MiOiJqb2UiLA0KICJleHAiOjEzMDA4MTkzODAsDQogImh0dHA6Ly9leGF
        tcGxlLmNvbS9pc19yb290Ijp0cnVlfQ",
      "signatures":[
       {"protected":"eyJhbGciOiJSUzI1NiJ9",
        "header":
         {"kid":"2010-12-29"},
        "signature":
         "cC4hiUPoj9Eetdgtv3hF80EGrhuB__dzERat0XF9g2VtQgr9PJbu3XOiZj5RZ
          mh7AAuHIm4Bh-0Qc_lF5YKt_O8W2Fp5jujGbds9uJdbF9CUAr7t1dnZcAcQjb
          KBYNX4BAynRFdiuB--f_nZLgrnbyTyWzO75vRK5h6xBArLIARNPvkSjtQBMHl
          b1L07Qe7K0GarZRmB_eSN9383LcOLn6_dO--xi12jzDwusC-eOkHWEsqtFZES
          c6BfI7noOPqvhJ1phCnvWh6IeYI2w9QOYEUipUTI8np6LbgGY9Fs98rqVt5AX
          LIhWkWywlVmtVrBp0igcN_IoypGlUPQGe77Rw"},
       {"protected":"eyJhbGciOiJFUzI1NiJ9",
        "header":
         {"kid":"e9bc097a-ce51-4036-9562-d2ade882db0d"},
        "signature":
         "DtEhU3ljbEg8L38VWAfUAqOyKAM6-Xx-F4GawxaepmXFCgfTjDxw5djxLa8IS
          lSApmWQxfKTUJqPP3-Kg6NU1Q"}]
}

JWE

JWS 仅仅是对声明(claims)作了签名,保证了其不被篡改,但是其 payload(中段负载) 信息是暴露的。也就是 JWS 仅仅能保证数据的完整性而不能保证数据不被泄露。它不适合传递敏感数据。JWE 的出现就是为了解决这个问题的。具体的可以看下图:

JWE 示意图
JWE 示意图

从上面可以看出 JWE 的生成非常繁琐,作为 Token 可能比较消耗资源和耗时。用作安全的数据传输途径应该不错。举个例子:

eyJhbGciOiJSU0EtT0FFUCIsImVuYyI6IkEyNTZHQ00ifQ.
OKOawDo13gRp2ojaHV7LFpZcgV7T6DVZKTyKOMTYUmKoTCVJRgckCL9kiMT03JGe
ipsEdY3mx_etLbbWSrFr05kLzcSr4qKAq7YN7e9jwQRb23nfa6c9d-StnImGyFDb
Sv04uVuxIp5Zms1gNxKKK2Da14B8S4rzVRltdYwam_lDp5XnZAYpQdb76FdIKLaV
mqgfwX7XWRxv2322i-vDxRfqNzo_tETKzpVLzfiwQyeyPGLBIO56YJ7eObdv0je8
1860ppamavo35UgoRdbYaBcoh9QcfylQr66oc6vFWXRcZ_ZT2LawVCWTIy3brGPi
6UklfCpIMfIjf7iGdXKHzg.
48V1_ALb6US04U3b.
5eym8TW_c8SuK0ltJ3rpYIzOeDQz7TALvtu6UG9oMo4vpzs9tX_EFShS8iB7j6ji
SdiwkIr3ajwQzaBtQD_A.
XFBoMYUZodetZdvTiFvSkQ

一共有五个部分,被四个英文句号隔开。

其实 JWE 也有对应的 JSON 格式,同样具有 JWS 的两种序列化方式,参见RFC7516

JWT 和 JWS、JWE 的关系

以下是RFC7519JWT的说明:

JWT 的定义

从上面可以得出一些结论:

  • JWT 有特定的 claims,这些claims以 JSON 的形式组成Payload
  • JWT 的结构可以是 JWS 或者 JWE。
  • JWT 的序列化方式只能使用 Compact Serialization,不能是 JSON Serialization。

简而言之,JWT 是包含了特定claims的 JWS 或者 JWE 字符串。我们常见的大部分都属于 JWS。

另外,我们通常读作JWT,实际建议读作jot(角特)。

JWK

JWK 是本文最重要的知识点,这对我们后面学习资源服务器(Resource Server)非常重要。

场景描述

我相信签名公私钥这个大家都不陌生。JWT 本身也要做使用私钥进行签名防止信息被篡改,公钥用来发给下游消费方来验证 JWT 的可靠性。通常情况下,公钥的配置方式为静态文件集成,这有一个弊端,当上游公私钥进行了改动,下游就无法动态进行公钥适配。这就是 JWK 要解决的问题,它对密码算法和标识符进行了规范设计,它紧凑的 JSON 数据结构非常方便在上下游之间传输。

JWK 格式

JWK 是表示加密密钥的 JSON 对象。该对象包含的key名称必须是唯一的,在此基础上 JWK 可以包含一些自定义字段。下面是一个 P-256 EC(椭圆曲线离散密码)密钥的 JWK 表示:

{
    "kty":"EC",
    "crv":"P-256",
    "x":"f83OJ3D2xF1Bg8vub9tLe1gHMzV76e8Tus9uPHvRVEU",
    "y":"x_FEzRu9m36HLN_tue659LNpXW6pCyStikYjKIWI5a0",
    "kid":"Public key used in JWS spec Appendix A.3 example"
}

按照RFC7517的定义,JWK JSON 对象可能包含以下属性:

JWK 的定义属性
JWK 的定义属性

根据不同的算法 JWK 还可能包含其它的属性。

JWK Set

JWK Set 表示一组具有不同kid的 JWK,这非常容易理解。它也是一个 JSON 对象,唯一的key就是keys。举个例子:

{"keys":
       [
         {"kty":"EC",
          "crv":"P-256",
          "x":"MKBCTNIcKUSDii11ySs3526iDZ8AiTo7Tu6KPAqv7D4",
          "y":"4Etl6SRW2YiLUrN5vfvVHuhp7x8PxltmWWlbbM4IFyM",
          "use":"enc",
          "kid":"1"},

         {"kty":"RSA",
          "n": "0vx7agoebGcQSuuPiLJXZptN9nndrQmbXEps2aiAFbWhM78LhWx
     4cbbfAAtVT86zwu1RK7aPFFxuhDR1L6tSoc_BJECPebWKRXjBZCiFV4n3oknjhMs
     tn64tZ_2W-5JsGY4Hc5n9yBXArwl93lqt7_RN5w6Cf0h4QyQ5v-65YGjQR0_FDW2
     QvzqY368QQMicAtaSqzs8KJZgnYb9c7d0zgdAZHzu6qMQvRL5hajrn1n91CbOpbI
     SD08qNLyrdkt-bFTWhAI4vMQFh6WeZu0fM4lFd2NcRwr3XPksINHaQ-G_xBniIqb
     w0Ls1jF44-csFCur-kEgU8awapJzKnqDKgw",
          "e":"AQAB",
          "alg":"RS256",
          "kid":"2011-04-29"}
       ]
     }

OAuth2 配置中的 JWK Set URL 就是输出 JWK Set 的端点。

JWA

JWA 规范规定了哪些算法可以作为 JWS 和 JWE 的密码算法。还规定了这些算法对应的 JWK 中的alg属性,以及特定算法在 JWK 包含的属性例如前面 EC 算法中的crvxy,这些属性并不是一成不变的,它们会根据算法的迭代进行调整。如果你对 JWA 的细节感兴趣,请参阅RFC7518

你可以通过JWK 生成器自行使用一些算法生成 JWK 观察不同算法之间的区别。

小结

今天对 JOSE 规范进行简单的介绍了解,对你学习 OAuth2 和 OIDC 相关的知识非常有帮助。不要求深入但是一定要了解相关的知识。

「点点赞赏,手留余香」

1

给作者打赏,鼓励TA抓紧创作!

微信微信 支付宝支付宝

还没有人赞赏,快来当第一个赞赏的人吧!

声明:本站所有文章,如无特殊说明或标注,均为本站原创发布。任何个人或组织,在未征得本站同意时,禁止复制、盗用、采集、发布本站内容到任何网站、书籍等各类媒体平台。如若本站内容侵犯了原著者的合法权益,可联系我们进行处理。
码云笔记 » 你只知道JWT,那JWE、JWS、JWK、JWA呢?

发表回复