当前位置: 首页 > 科技观察

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

时间:2023-03-21 18:44:23 科技观察

移动端的兴起,OAuth2的流行,让JWT这几年乱成一锅粥。今天要介绍的是另一个规范集JOSE[1],全称是JavascriptObjectSigningandEncryption,与JWT有很大的关系。JOSE简介JOSE是一个Javascript对象签名和加密协议,其目的是提供一种在各个通信方之间安全地传输声明(claims,如授权信息)的方法。易于在程序中使用。目前规范还在发展中,我们常用的RFC文档定义的概念如下:JWSJSONWebsignature,content(MAC)基于JSON数据结构,采用数字签名技术或消息认证码技术进行保护,可称为JWS。本规范使用的密码算法和标识符在另一个规范JWA中定义。更多规则参见RFC7515[2],这里我们可以通过连载来感受一下。JWS序列化JWS的序列化分为JWSCompactSerialization和JWSJSONSerialization。JWS紧凑序列化序列化表示为URL安全的紧凑字符串。格式为:BASE64URL(UTF8(JWSProtectedHeader))||'.'||BASE64URL(JWS负载)||'.'||BASE64URL(JWSSignature)例如:eyJhbGciOiJFUzI1NiJ9.eyJpc3MiOiJqb2UiLA0KICJleHAiOjEzMDA4MTkzODAsDQogImh0dHA6Ly9leGFtcGxlLmNvbS9pc19yb290Ijp0cnVlfQ.DtEhU3ljbEg8L38VWAfUAqOyKAM6-Xx-F4GawxaepmXFCgfTjDxw5djxLa8ISlSApmWQxfKTUJqPP3-Kg6NU1QJWT通常That'stheformat.JWSJSONSerialization序列化表示为一个JSON对象,有两种格式。一般格式为:{"payload":"","signatures":[{"protected":"","header":"“,"signature":""},{"protected":"","header":"","signature":""}]}平铺格式为:{"payload":"","protected":"","header":"“,“签名”:“<签名内容>”}举举个一般一般:{“有效载荷”:eyJhbGciOiJSUzI1NiJ9","header":{"kid":"2010-12-29"},"signature":"cC4hiUPoj9Eetdgtv3hF80EGrhuB__dzERat0XF9g2VtQgr9PJbu3XOiZj5RZmh7AAuHIm4Bh-0Qc_lF5YKt_O8W2Fp5jujGbds9uJdbF9CUAr7t1dnZcAcQjbKBYNX4BAynRFdiuB--f_nZLgrnbyTyWzO75vRK5h6xBArLIARNPvkSjtQBMHlb1L07Qe7K0GarZRmB_eSN9383LcOLn6_dO--xi12jzDwusC-eOkHWEsqtFZESc6BfI7noOPqvhJ1phCnvWh6IeYI2w9QOYEUipUTI8np6LbgGY9Fs98rqVt5AXLIhWkWywlVmtVrBp0igcN_IoypGlUPQGe77Rw"},{"protected":"eyJhbGciOiJFUzI1NiJ9","header":{"kid":"e9bc097a-ce51-4036-9562-d2ade882db0d"},"signature":"DtEhU3ljbEg8L38VWAfUAqOyKAM6-Xx-F4GawxaepmXFCgfTjDxw5djxLa8ISlSApmWQxfKTUJqPP3-Kg6NU1Q"}]}JWEJWS只是在claims上签名以确保它们不会被篡改,但它的payload(中间负载)信息是JWS只能保证的完整性数据,但不能保证数据不会被泄露。它不适合传递敏感数据。JWE的出现就是为了解决这个问题。详见下图:JWE图从上图可以看出JWE的生成非常繁琐,作为Token可能会消耗资源和时间。作为安全的数据传输路径应该没问题。举个例子:eyJhbGciOiJSU0EtT0FFUCIsImVuYyI6IkEyNTZHQ00ifQ.OKOawDo13gRp2ojaHV7LFpZcgV7T6DVZKTyKOMTYUmKoTCVJRgckCL9kiMT03JGeipsEdY3mx_etLbbWSrFr05kLzcSr4qKAq7YN7e9jwQRb23nfa6c9d-StnImGyFDbSv04uVuxIp5Zms1gNxKKK2Da14B8S4rzVRltdYwam_lDp5XnZAYpQdb76FdIKLaVmqgfwX7XWRxv2322i-vDxRfqNzo_tETKzpVLzfiwQyeyPGLBIO56YJ7eObdv0je81860ppamavo35UgoRdbYaBcoh9QcfylQr66oc6vFWXRcZ_ZT2LawVCWTIy3brGPi6UklfCpIMfIjf7iGdXKHzg.48V1_ALb6US04U3b.5eym8TW_c8SuK0ltJ3rpYIzOeDQz7TALvtu6UG9oMo4vpzs9tX_EFShS8iB7j6jiSdiwkIr3ajwQzaBtQD_A.XFBoMYUZodetZdvTiFvSkQ一共有五个部分,被四个英文句号隔开。Infact,JWEalsohasacorrespondingJSONformat,whichalsohastwoserializationmethodsofJWS,seeRFC7516[3].TherelationshipbetweenJWT,JWS,andJWEisasfollows:RFC7519[4]explainsJWT:thedefinitionofJWTFromtheabove,someconclusionscanbedrawn:JWThasspecificclaims,andtheseclaimsformPayloadintheformofJSON.ThestructureofJWTcanbeJWSorJWE.TheserializationmethodofJWTcanonlyuseCompactSerialization,notJSONSerialization.Inshort,aJWTisaJWSorJWEstringthatcontainsspecificclaims.MostofourcommononesbelongtoJWS.Inaddition,weusuallyreaditasJ,W,T,andactuallyrecommenditasjot.ForthedefinitionandspecificationofJWT,pleaserefertoRFC7519[5].JWKJWKisthemostimportantknowledgepointinthisarticle,whichisveryimportantforustolearnResourceServerlater.场景描述对于公钥和私钥的签名相信大家都不陌生。JWT本身也必须用私钥签名,防止信息被篡改,公钥用于发送给下游消费者验证JWT的可靠性。通常公钥的配置方式是静态文件集成,有一个缺点。当上游公私钥发生变化时,下游无法动态适配公钥。这是JWK要解决的问题。它规范了密码算法和标识符的设计,其紧凑的JSON数据结构非常方便上下游之间的传输。JWK格式JWK是表示加密密钥的JSON对象。该对象包含的键名必须是唯一的,基于此JWK可以包含一些自定义字段。这是P-256EC(椭圆曲线离散密码)密钥的JWK表示:{"kty":"EC","crv":"P-256","x":"f83OJ3D2xF1Bg8vub9tLe1gHMzV76e8Tus9uPHvRVEU","y":"x_FEzRu9m36HLN_tue659LNpXW6pCyStikYjKIWI5a0","kid":"PublickeyusedinJWSspecAppendixA.3example"}根据RFC7517[6]的定义,JWKJSON对象可能包含以下属性:JWK定义属性也可能包含JWK根据到不同的算法其他属性。JWKSetJWKSet代表一组不同kid的JWK,非常好理解。它也是一个JSON对象,唯一的键是键。例如:{“keys”:[{“kty”:“EC”,“crv”:“P-256”,“x”:“MKBCTNIcKUSDii11ySs3526iDZ8AiTo7Tu6KPAqv7D4”,“y”:“4Etl6SRW2YiLUrN5vfvVHuhp7x8PxltmWWlbbM4IFyM”,“使用”:“enc","kid":"1"},{"kty":"RSA","n":"0vx7agoebGcQSuuPiLJXZptN9nndrQmbXEps2aiAFbWhM78LhWx4cbbfAAtVT86zwu1RK7aPFFxuhDR1L6tSoc_BJECPebWKRXjBZCiFV4n3oknjhMstn64tZ_2W-5JsGY4Hc5n9yBXArwl93lqt7_RN5w6Cf0h4QyQ5v-65YGjQR0_FDW2QvzqY368QQMicAtaSqzs8KJZgnYb9c7d0zgdAZHzu6qMQvRL5hajrn1n91CbOpbISD08qNLyrdkt-bFTWhAI4vMQFh6WeZu0fM4lFd2NcRwr3XPksINHaQ-G_xBniIqbw0Ls1jF44-csFCur-kEgU8awapJzKnqDKgw","e":"AQAB","alg":"RS256","kid":"2011-04-29"}]}OAuth2配置中的JWKSetURL是输出JWKSet的端点。JWAJWA规范指定了哪些算法可以用作JWS和JWE的密码算法。还规定了这些算法对应的JWK中的alg属性,以及之前EC算法中针对特定算法的crv、x、y等JWK中包含的属性。这些属性不是静态的,会随着算法的迭代而调整。如果您对JWA的细节感兴趣,请参考RFC7518[7]。可以使用一些算法通过JWK生成器[8]生成JWK,观察不同算法之间的区别。小结今天简单介绍一下JOSE规范,对大家了解OAuth2和OIDC会有很大的帮助。不要求深入,但必须了解相关知识。参考文献:[1]JOSE:https://datatracker.ietf.org/wg/jose/documents/[2]RFC7515:https://datatracker.ietf.org/doc/rfc7515/[3]RFC7516:https://datatracker.ietf.org/doc/rfc7516/[4]RFC7519:https://datatracker.ietf.org/doc/rfc7519/[5]RFC7519:https://datatracker.ietf.org/doc/rfc7519/[6]RFC7517:https://datatracker.ietf.org/doc/rfc7517/[7]RFC7518:https://datatracker.ietf.org/doc/rfc7518/[8]JWK生成器:https://mkjwk.org/