zoukankan      html  css  js  c++  java
  • flask项目--认证方案Json Web Token(JWT)

    网上大多数介绍JWT的文章实际介绍的都是JWS(JSON Web Signature),也往往导致了人们对于JWT的误解,但是JWT并不等于JWS,JWS只是JWT的一种实现,除了JWS外,JWE(JSON Web Encryption)也是JWT的一种实现。

    JWS

    • 头部(Header)
      头部用于描述关于该JWT的最基本的信息
      例如:其类型、以及签名所用的算法等。
      JSON内容要经Base64 编码生成字符串成为Header。

    • 载荷(PayLoad)
      payload的五个字段都是由JWT的标准所定义的。
      iss: 该JWT的签发者
      sub: 该JWT所面向的用户
      aud: 接收该JWT的一方
      exp(expires): 什么时候过期,这里是一个Unix时间戳
      iat(issued at): 在什么时候签发的
      后面的信息可以按需补充。 JSON内容要经Base64 编码生成字符串成为PayLoad。

    • 签名(signature)
      这个部分header与payload通过header中声明的加密方式,使用密钥secret进行加密,生成签名。
      JWS的主要目的是保证了数据在传输过程中不被修改,验证数据的完整性。
      但由于仅采用Base64对消息内容编码,因此不保证数据的不可泄露性。所以不适合用于传输敏感数据。

    JWE

    相对于JWS,JWE则同时保证了安全性与数据完整性。 JWE由五部分组成:

    JWE的计算过程相对繁琐,不够轻量级,因此适合与数据传输而非token认证,但该协议也足够安全可靠,用简短字符串描述了传输内容,兼顾数据的安全性与完整性

    • JWE组成
      具体生成步骤为:
      JOSE含义与JWS头部相同。
      生成一个随机的Content Encryption Key (CEK)。
      使用RSAES-OAEP 加密算法,用公钥加密CEK,生成JWE Encrypted Key。
      生成JWE初始化向量。
      使用AES GCM加密算法对明文部分进行加密生成密文Ciphertext,算法会随之生成一个128位的认证标记Authentication Tag。 6.对五个部分分别进行base64编码。

    1. jwt

    • VS状态保持机制
      1.APP不支持状态保持
      2.状态保持有同源策略, 默认无法跨服务器传递(nginx可以处理)

    • JWT不会对数据进行加密, 所以数据中不要存放有阅读价值的数据

    • 不可逆加密

      • md5 sha1 sha256
      • 主要用于数据认证, 防止数据被修改

    消息摘要 MD

    • 哈希算法:
      将任意长度内容转为定长内容, 且相同内容的哈希值始终相同, 不同内容的哈希值不同(极小概率出现碰撞)
      由于其唯一性, 一般将数据的哈希值称为数据的摘要信息, 称为数据的"指纹", 用于检测数据是否被修改
    • 代表算法 sha1 sha256 md5
    • 缺点:哈希算法是公开的, 如果可以获取到明文, 就可以穷举出使用的算法

    消息认证 MA ( JWT一般会采用消息认证机制)

    哈希算法基础上混入秘钥, 防止哈希算法被破解, 避免签名被伪造

    • 代表算法 hmacsha256

    2. PyJWT (重点)

    • 安装 pip install PyJWT
    import jwt
    from jwt import PyJWTError
    from datetime import datetime, timedelta
    
    
    payload = {  # jwt设置过期时间的本质 就是在payload中 设置exp字段, 值要求为格林尼治时间
        "user_id": 1,
        'exp': datetime.utcnow() + timedelta(seconds=30)
    }
    
    screct_key = "test"
    # 生成token
    token = jwt.encode(payload, key=screct_key, algorithm='HS256')
    print(token)
    
    # 验签token  返回payload    pyjwt会自动校验过期时间
    try:
        data = jwt.decode(token, key=screct_key, algorithms='HS256')
        print(data)
    except PyJWTError as e:
        print("jwt验证失败: %s" % e)
    

    3. 数字签名 (拓展)

    • 消息认证存在缺点
      • 之前没有对服务器返回的数据进行验签, 无法确认数据是否被修改(服务器身份是否合法)
      • 将秘钥交给客户端, 客户端才可以验签服务器返回的数据是否被修改
      • 但是客户端安全性较差, 一旦秘钥泄露, 仍然可以伪造签名
    • 利用非对称加密对摘要信息进行加密, 避免摘要信息被伪造
    • 非对称加密采用秘钥对
      • 公钥和私钥
      • 公钥加密, 私钥解密
      • 私钥加密, 公钥解密
      • 私钥可以推出公钥, 公钥无法推出私钥
    • 发送者使用私钥对数据摘要加密(签名), 接收者使用对应的公钥解密, 然后对数据进行哈希处理, 比对摘要信息是否一致(验签)
    • 代表算法 RSA
    • 使用场景
      • 安全级别要求比较高的系统, 如银行等
    • 优点
      • 客户端不会像消息认证一样保存秘钥, 而是保存了非对称加密的公钥, 即使客户端被破解, 公钥被获取, 也无法通过公钥生成合法的签名
    • 缺点
      • 效率低

    • 使用openssl 生成RSA秘钥对
    # 生成私钥,指定私钥的长度为2048bit   1024基本安全, 2048非常安全
    openssl genrsa -out rsa_private_key.pem 2048
    # 根据私钥生成对应的公钥
    openssl rsa -in rsa_private_key.pem -pubout -out rsa_public_key_2048.pub
    # 私钥转化成pkcs8格式, 非必须,pkcs8格式解析起来更方便
    openssl pkcs8 -topk8 -inform PEM -in rsa_private_key.pem -outform PEM -nocrypt > rsa_private_key_pkcs8.pem
    
    • 安装RSA类库pip install cryptography
  • 相关阅读:
    HTML <input> 标签
    HTML5 <input> type 属性
    静态页面与动态页面
    string::size_type 页73 size_t 页90
    template method(模板方法)
    C++中创建对象的时候加括号和不加括号的区别(转)
    _declspec(dllexport)和.def(转)
    智能指针
    C++中的delete加深认识
    工厂方法(整理自李建忠<C++设计模式>视频)
  • 原文地址:https://www.cnblogs.com/oklizz/p/11414429.html
Copyright © 2011-2022 走看看