前后端通讯:非敏感信息Cookie的"强化"之路

本文涉及的产品
密钥管理服务KMS,1000个密钥,100个凭据,1个月
简介: 我们公司鉴权走的是JWT,但是有些数据走Cookie更方便通讯,纵观今天,网上一大把说Cookie不好的文章.但是我们还是要用,那怎么安全一丢丢呢?

网络异常,图片无法展示
|


前言


我们公司鉴权走的是JWT,


但是有些数据走Cookie更方便通讯,


纵观今天,网上一大把说Cookie不好的文章.


但是我们还是要用,那怎么安全一丢丢呢?

Cookie的痛点


  • 不同浏览器支持的数量不等,比较新的主流浏览器还好


  • 信息承载量有限,一般不能超过4kb


  • 容易遭受CSRF(跨站请求伪造)等攻击

聚焦场景


非敏感信息依赖cookie通讯(需要一定的安全性支持)

解决姿势


CSRF及XSS


常规姿势有这么写(请求头):


  • Content Security Policy
  • Referer: 判断来源ip或者url
  • Token: 自定义请求头对比也是可行的
  • HttpOnly: 客户端只读状态
  • SameSite: Strict会完全阻止第三方cookie,lax会宽松些

加密Cookie信息


若是觉得服务端的一些限制条件还不够,


我们可以适当采取一些手段来加密我们的Cookie!


哪怕暴露了Cookie也不会直接把数据暴露!!


比如,我经手过的落地姿势有: Base64+AES+UUID!


这个方案是很直白,支持度也很好(前后端).


具体加密原理可以自行引擎了解!


我们在这里讨论姿势,前端的支持如下!


  • Base64: IE10+起步就原生支持(window.atob,window.btoa)
  • AES: 非常流行的块加密姿势, 密文块匹配正确才能解码,破解还是相当难的,一般人玩不来!
  • UUID: 简称通用唯一识别码,其实你搞个随机数或者其他都行.这里用来混淆!


我们在AES的前后拼接特殊字符串或者nanoid是为了增大破解难度,


不至于Base64解码后就是Raw AES Text!!!

演示代码


此处用了Vue Cli初始化了一个项目来演示,


部分边缘情况判断就没有考虑很全了,


然而我们实际项目中,


更倾向于把这部分逻辑抽成utils或者hooks!


里面会考虑的边缘情况比较全面!


<script>
import {nanoid} from 'nanoid'
import AES from "crypto-js/aes";
import EncUTF8 from "crypto-js/enc-utf8";
export default {
  name: "App",
  data() {
    return {
      info: Object.freeze({
        version: "v1.0.0",
        EngineCode: "312312fasdfasrewrwe",
      }), // 需要加密的文本
      tempInfo: {}, // 中间变量,缓存转换的
    };
  },
  methods: {
    isJSON(str) {
      if (!str) return false;
      if (typeof str === "string") {
        try {
          let obj = JSON.parse(str);
          if (typeof obj === "object" && obj) {
            return true;
          } else {
            return false;
          }
        } catch (e) {
          console.log("error:" + str + "!!!" + e);
          return false;
        }
      }
    },
  },
  created() {
    console.time('nanoid 8位数生成时间')
      console.log(nanoid(8));
    console.timeEnd('nanoid 8位数生成时间')
    console.time('加密时间')
    console.log('%c 🍩 加密前信息: ', 'font-size:20px;background-color: #33A5FF;color:#fff;', this.info);
    // aes加密后的纯文本
    let encryptText = AES.encrypt(JSON.stringify(this.info), "cqmyg").toString();
    console.log('%c 🍩 encryptText: ', 'font-size:20px;background-color: #33A5FF;color:#fff;', encryptText);
    // 拼接八位数的随机字符作为前缀(用来混淆)
    let UUIDText = `${nanoid(8)}${encryptText}`
    console.log('%c 🥡 UUIDText: ', 'font-size:20px;background-color: #42b983;color:#fff;', UUIDText);
    // base64
    this.tempInfo = window.btoa(UUIDText);
    console.log(
      "%c 🌰 AES+NanoID+Base64加密后的文本: ",
      "font-size:20px;background-color: #EA7E5C;color:#fff;",
      this.tempInfo
    );
    console.timeEnd('加密时间')
  },
  mounted() {
    console.time("解密时间");
    if(this.tempInfo && typeof this.tempInfo === 'string'){
      let aesText = window.atob(this.tempInfo).slice(8);
      console.log('%c 🥫 aesText: ', 'font-size:20px;background-color: #ED9EC7;color:#fff;', aesText);
      let infoText = AES.decrypt(aesText, "cqmyg").toString(EncUTF8);
      console.log('%c 🍨 infoText: ', 'font-size:20px;background-color: #E41A6A;color:#fff;', infoText);
      let rawInfo = this.isJSON(infoText) ? JSON.parse(infoText): infoText;
      console.log('%c 🍐 解密得出的信息: ', 'font-size:20px;background-color: #EA7E5C;color:#fff;', rawInfo);
    }
    console.timeEnd("解密时间");
  },
  render(){
    return <div class="app">
      我是app
    </div>
  }
};
</script>


测试结果


网络异常,图片无法展示
|


多次测试下,浏览器端平均时长均在5ms以下,


但是我觉得主流浏览器波动都不会相差太大,


顶多20ms内,这个时间是可以接受的~



若是你还是觉得有点长,


可以去掉base64和nanoid,


只保留AES加解密!!

目录
相关文章
|
7月前
|
前端开发
解决前端ajax跨域请求不携带cookie信息JSESSIONID的问题
解决前端ajax跨域请求不携带cookie信息JSESSIONID的问题
|
3月前
|
存储 缓存 数据处理
php学习笔记-php会话控制,cookie,session的使用,cookie自动登录和session 图书上传信息添加和修改例子-day07
本文介绍了PHP会话控制及Web常用的预定义变量,包括`$_REQUEST`、`$_SERVER`、`$_COOKIE`和`$_SESSION`的用法和示例。涵盖了cookie的创建、使用、删除以及session的工作原理和使用,并通过图书上传的例子演示了session在实际应用中的使用。
php学习笔记-php会话控制,cookie,session的使用,cookie自动登录和session 图书上传信息添加和修改例子-day07
|
4月前
|
数据安全/隐私保护
在某网站的登录页面登录时如果选择“记住用户名”,登录成功后会跳转到一个中间层(页面代码将登录的用户名和密码存在cookie),中间页面中存在一个超链接,单击超链接可以链接到第三个页面查看信息。若选择“
该博客文章通过示例代码和运行结果截图,展示了网站登录过程中如何通过中间层页面使用cookies技术实现“记住用户名”功能,并在点击超链接后查看保存的用户名和密码信息。
在某网站的登录页面登录时如果选择“记住用户名”,登录成功后会跳转到一个中间层(页面代码将登录的用户名和密码存在cookie),中间页面中存在一个超链接,单击超链接可以链接到第三个页面查看信息。若选择“
|
4月前
|
存储 C#
【Azure APIM】APIM 策略语句如何读取请求头中所携带的Cookie信息并保存为变量
【Azure APIM】APIM 策略语句如何读取请求头中所携带的Cookie信息并保存为变量
|
4月前
|
数据安全/隐私保护
|
6月前
|
安全 Java Maven
如何使用jsoup实现网站登录,cookie保存,查询信息
【6月更文挑战第11天】如何使用jsoup实现网站登录,cookie保存,查询信息
242 1
|
7月前
|
存储 安全 Java
基于 Cookie 的信息共享机制
基于Cookie的信息共享机制用于客户端状态保持。Cookie是服务器生成并发送到浏览器的文本文件,存储用户状态和安全信息。当用户发起请求时,浏览器会将Cookie一并发送,服务器据此处理。Cookie分为内存和硬盘两种,有持久和非持久之分,但因以明文存储,存在安全隐患。JSP/Servlet中的Cookie类提供管理方法。示例代码展示了如何使用JSP设置和检查Cookie。需注意Cookie的安全问题,避免数据泄露。
87 3
|
6月前
|
安全 Java Maven
使用jsoup实现网站登录,cookie保存,查询信息
【6月更文挑战第7天】使用jsoup实现网站登录,cookie保存,查询信息
102 0
|
存储 缓存 JSON
36.从入门到精通:CGI环境变量 GET和POST方法 GET方法 POST方法 CGI中使用Cookie Cookie设置 检索Cookie信息
36.从入门到精通:CGI环境变量 GET和POST方法 GET方法 POST方法 CGI中使用Cookie Cookie设置 检索Cookie信息
|
NoSQL Redis
SpringSession的源码解析(从Cookie中读取Sessionid,根据sessionid查询信息全流程分析)
上一篇我们介绍了SpringSession中Session的保存过程,今天我们接着来看看Session的读取过程。相对保存过程,读取过程相对比较简单。 本文想从源码的角度,详细介绍一下Session的读取过程。
390 0
SpringSession的源码解析(从Cookie中读取Sessionid,根据sessionid查询信息全流程分析)