JWT(JSON Web Tokens)

1.JWT即JSON Web Tokens,他可以用来安全的传递信息,因为这些信息是经过数字签名的

2.JWT可以使用一种加密算法比如HMAC 算法,也可以使用公钥/私钥的非对称算法

3.因为JWT签名后的信息够短,可以放在url里、request body里、http header里,传输够快。

4.荷载信息里包含所有你想要的,避免不止一次的去查询数据库

5.JWT的使用场景主要包括:

  1) 认证,这是比较常见的使用场景,只要用户登录过一次系统,之后的请求都会包含签名出来的token,通过token也可以用来实现单点登录。

  2)交换信息,通过使用密钥对来安全的传送信息,可以知道发送者是谁、放置消息被篡改。

6.JSON Web Tokens由三部分组成,用英文句点分割(.) ,一般看起来例如:xxxxx.yyyyy.zzzzz

分为:

  • Header  头信息
  • Payload  荷载信息,实际数据
  • Signature  由头信息+荷载信息+密钥 组合之后进行加密得到

  1) Header 头信息通常包含两部分,type:代表token的类型,这里使用的是JWT类型。 alg:使用的Hash算法,例如HMAC SHA256或RSA.

{
  "alg": "HS256",
  "typ": "JWT"
}
// 这会被经过base64Url编码形成第一部分

  2)Payload  一个token的第二个部分是荷载信息,它包含一些声明Claim(实体的描述,通常是一个User信息,还包括一些其他的元数据)

    声明分三类:

    1)Reserved Claims,这是一套预定义的声明,并不是必须的,这是一套易于使用、操作性强的声明。包括:iss(issuer)、exp(expiration time)、sub(subject)、aud(audience)等

    2)Plubic Claims,

    3)Private Claims,交换信息的双方自定义的声明

  

{
  "sub": "1234567890",
  "name": "John Doe",
  "admin": true
}
// 同样经过Base64Url编码后形成第二部分

  3) signature  使用header中指定的算法将编码后的header、编码后的payload、一个secret进行加密

  例如使用的是HMAC SHA256算法,大致流程类似于: HMACSHA256( base64UrlEncode(header) + "." + base64UrlEncode(payload), secret)

  这个signature字段被用来确认JWT信息的发送者是谁,并保证信息没有被修改

7.这个JSON Web Tokens包含了必要的用户信息,减少了对数据库进行多次查询的需要。

8.由于没有使用Cookies,Cross-Origin Resource Sharing (CORS) ,跨域的资源访问不会成为问题。

 JWT官网有一张图描述了JWT的认证过程:

9.JWT、JWS、JWE的区别(转自https://securedb.co/community/jwt-vs-jws-vs-jwe/)

  1)JWT(JSON Web Tokens),jwt长度较小,且可以使用URL传输(URL safe)。不想cookies只能在web环境起作用。 JWT可以同时使用在web环境和RESTfull的接口。

  2)对于开发者来说,JWT与另外两种相近的标准:JWS(JSON Web Signature)、JWE(JSON Web Encryption),容易引起混乱。

  3)关于JWT的描述,可以参考RFC7519(https://tools.ietf.org/html/rfc7519)的描述:

    JSON Web Token (JWT) 是一个间接地、URL安全的,表现为一组声明,可以在双方之间进行传输。一个JWT的声明,是指经过编码后的一个JSON对象,这个JSON对象可以是一个JSON Web     Signature(JWS)结构的荷载(payload),或者是一个JSON Web Encryption(JWE)结构的明文。允许使用声明进行数字签名,或者通过一个Message Authentication Code(MAC)进行完整性保护可选择是否加密。

    简单来说,JWTs表现为一组被编码为JWS and/or JWE结构的JSON object的声明(Claim).

    换言之,一组JWT声明(就是表现为JSON格式的Claims)被通过JWS结构或者JWE结构(或者同时使用两种)发送,决定于你如何去实现它。所以,当你发送JWT给别人是,它实际上是一个JWT荷载或者JWE荷载。JWS荷载更加常用。

  关于声明(Claim),他们是关于用户的简单断言(assertion)。比如,对于一个用户在工资系统中进行认证,这组Claims可能看起来像这样:

  

{
    "userId":"johndoe",
    "role":"employee",
    "pay-frequency":"biweekly"
}

  现在,将它嵌入一个JWS结构,整个字符串看起来像是这样:

 

{    
    "alg":"HS256"
} // End of JOSE Header
. 
{
    "userId": "johndoe",
    "role": "employee",
    "pay-frequency": "biweekly"
} // End of JWT Claims
.
{
 
} // End of Signature in case of JWS

  4)关于JWS

  顾名思义,JWS模式对这个内容进行了数字化签名。这个内容被用来存放JWT的声明.服务端签名出JWT并且发送到客户端,并在用户成功认证后进行应答。服务器期望客户端在下次请求的时候将JWS作为请求的一部分,发送回服务端。

  如果我们处理的客户端是欺骗者则么办?这就是签名(signature)需要出场的地方了。签名携带了完整的可验证的信息。换句话说,服务器可以确认,接收到的JWT声明里的JWS是没有经过欺骗客户端、中间者进行修改的。

  服务端通过验证消息的签名来确保客户端没有修改声明。如果服务端检测到任何修改,可以采取适当的动作(拒绝这次请求或者锁定客户端之类的)

  客户端同样可以验证签名,为了做到这点,客户端也需要服务端的secret(密钥)(如果这个JWT签名是HMAC算法),或者需要服务端对公钥(如果这个WJT是数字化签名)

  特别注意:对于JWS,荷载(声明部分)没有进行加密,所以,不要发送任何敏感信息.

  5)关于JWE

  JWE模式会对内容加密,而不是签名。JWT的声明会被加密。因此JWE带来了保密性。JWE可以被签名并附在JWS里。这样的话就可以同时加密和签名。因此得到了保密性(Confidentiality)、完整性(Integrity)、可认证(Authentication)。

  6)那么对于客户端,如何分辨JWS或者JWE呢?

  JWS的Header与JWE的Header是不同的,可以通过检查“alg”Header参数的值来区分。如果这个值表现为一个数字签名或者MAC的算法,或者是”none“,则它是一个JWS。

    如果它表现为一个 Key Encryption, Key Wrapping, Direct Key Agreement, Key Agreement with Key Wrapping, or Direct Encryption algorithm。则它是一个JWE。

  还可以通过Header里的“enc”(encryption algorithm)是否存在来判断,如果"enc"这个成员存在的话说明是JWE,否则的话就是JWS.

 

posted @ 2016-10-27 22:49  在修行  阅读(22732)  评论(1编辑  收藏  举报