zoukankan      html  css  js  c++  java
  • JWT token组成

    JWT token的组成

    JWT token由三个部分组成,头部(header)、有效载荷(payload)、签名(signature),
    官网: https://jwt.io/

    header部分由 typ 和 alg 组成,typ的全称是(type,类型)、alg全称(algorithm,算法),类型可以自己定义,没有限制。而alg: HS256,表示当前的token是使用HS256算法来进行加密的。HS256实际上是一种签名算法。
    首先我们要了解几个名词:

    • 数字签名,数字签名和我们平常在文件中签上自己的名字是一样的,数字签名是为了防止伪造。
    • 数字摘要/数据指纹: 一般来说指的就是数据的hash值,比如SHA1/SHA256/SHA512/MD5等,这些都是常见的摘要算法,最简单的例子是我们在网上下载一个软件时,软件会有一个md5的编码,一般为了安全起见,
      都会让我们去验证下载下来的软件的md5和官方的md5是否匹配,如果匹配就表示没有被串改过
    • 加密算法,这个就比较容易理解了,就是直接对数据进行加密,加密算法和摘要算法最大的区别就是,加密是可逆的。常见的加密算法有对称加密和非对称加密等。
      数字签名一般的实现是,先对一个原始数据进行一次HASH摘要,然后再使用非对称加密算法(RSA、ECC等)对这个摘要进行加密,这样得到的结果就是原始数据的一个签名。
      那么用户在验证数据的时候,只需要使用公钥对签名进行解密,然后得到一组hash的摘要,用这个摘要和要比较的目标数据的摘要再进行比较,如果这两个摘要相等,说明验证成功,否则则验证失败。
      而在JWT中,提供了好几种签名算法的支持,分别是:
    • HS256, 这种签名算法是表示采用同一个[secret-key]进行签名与验证,这种就是属于对称加密的验证方式,一旦[secret_key]泄露,就无法保证安全性。
    • RS256,RS256采用的是RSA非对称加密算法来进行加密,使用公钥进行验证,通过私钥进行加密,公钥即使泄露也不会有影响,只需要确保私钥的安全即可。
    • ES256,ES256和RS256是一样的,都是使用私钥签名、公钥验证,算法速度上的差距也不大,但是ES算法的长度相对来说要短一些。

    对于单体应用来说,HS256和RS256的安全性相差不大,如果是在微服务架构中,需要多方验证的场景,使用RS256/ES256的安全性会更高。

    Header部分的数据,是通过base64位进行编码

    ** { “typ”: “JWT”, “alg”: “HS256” }** base64编码 http://tool.oschina.net/encrypt?type= 3 ** eyAKInR5cCI6ICJKV1QiLCAKImFsZyI6ICJIUzI1NiIKfSAK**

    payLoad

    Payload 里面是 Token 的具体内容,也是一个json字符串,这些内容里面有一些是标准字段,你也可以添加其它需要的内容;payload的json结构并不像header那么简单,payload用来承载要传递的数据,
    它的json结构实际上是对JWT要传递的数据的一组声明,这些声明被JWT标准称为claims , JWT默认提供了一些标准的Claim,具体内容如下。

    • iss(Issuser):代表这个JWT的签发主体;
    • sub(Subject):代表这个JWT的主体,即它的所有人;
    • aud(Audience):代表这个JWT的接收对象;
    • exp(Expiration time):是一个时间戳,代表这个JWT的过期时间;
    • nbf(Not Before):是一个时间戳,代表这个JWT生效的开始时间,意味着在这个时间之前验证JWT是会失败的;
    • iat(Issued at):是一个时间戳,代表这个JWT的签发时间;
    • jti(JWT ID):是JWT的唯一标识。

    按照JWT标准的说明:标准的claims都是可选的,在生成playload不强制用上面的那些claim,你可以完全按照自己的想法来定义payload的结构,不过这样做根本没必要:

    • 第一是,如果把JWT用于认证, 那么JWT标准内规定的几个claim就足够用了,甚至只需要其中一两个就可以了,假如想往JWT里多存一些用户业务信息,比如角色和用户名等,这倒是用自定义的claim来添加;
    • 第二是,JWT标准里面针对它自己规定的claim都提供了有详细的验证规则描述,每个实现库都会参照这个描述来提供JWT的验证实现,所以如果是自定义的claim名称,那么你用到的实现库就不会主动去验证这些claim。
      同样,payLoad中的数据,也是拼接好之后,通过base64进行编码,得到一个目标字符串。

    signature

    signature表示签名,它的组成是。

    signature=HS256(base64(header)+"."+base64(payload),secret_key)
    

    签名的组成是,把header、payload分别通过base64进行编码,然后拼接在一起,使用 . 作为分隔符。

    再通过header中声明的签名方法进行整体签名,其中HS256是一种对称加密方法,需要指定一个secret_key。最终得到的signature就成为了jwt中的第三个部分。

    最后将这3个部分组成一个完整的字符串构成了JWT:base64(header)+”.”+base64(payload)+”.”+sinature 。 这就是JWT的核心。

    secret_key是保存在服务器端的,jwt的签发生成也是在服务器端的,secret就是用来进行jwt的签发和jwt的验证,所以,它在任何场景都不应该流露出去。一旦客户端得知这个secret_key, 那就意味着客户端是可以自我签发jwt了

  • 相关阅读:
    LeetCode Array Easy 414. Third Maximum Number
    LeetCode Linked List Medium 2. Add Two Numbers
    LeetCode Array Easy 283. Move Zeroes
    LeetCode Array Easy 268. Missing Number
    LeetCode Array Easy 219. Contains Duplicate II
    LeetCode Array Easy 217. Contains Duplicate
    LeetCode Array Easy 189. Rotate Array
    LeetCode Array Easy169. Majority Element
    LeetCode Array Medium 11. Container With Most Water
    LeetCode Array Easy 167. Two Sum II
  • 原文地址:https://www.cnblogs.com/snail-gao/p/14140811.html
Copyright © 2011-2022 走看看