怎样在vue中使用rsa加解密

14 篇文章 0 订阅
1 篇文章 0 订阅

vue项目中使用RSA加解密

在最近的开发中,因为对数据有保密要求,所以需要对所有post请求进行RSA加密操作。
加密原理就不多说了,直接上代码说怎么用

1、首先我在在工具类文件夹里新建了一个utils.js文件,对加密解密进行封装

/**
 * 工具类
 */
import Vue from "vue";
import JsEncrypt from "encryptlong"; //因为请求数据较多,使用了encryptlong加密包,原理跟encrypt一致
export default {	//导出暴露方法
  //RSA加密方法
  RSAencrypt(key, obj) {  //key为加密公钥,obj为需要加密的数据
    let encrypt = new JsEncrypt();
    encrypt.setPublicKey(key); //设置加密公钥
    return encrypt.encryptLong(obj);	//返回通过encryptLong方法加密后的结果
  },
  //RSA解密方法
  RSAdecrypt(key, obj) {	//key为解密私钥,obj为需要解密的数据
    let _decryp = new JsEncrypt();
    _decryp.setPrivateKey(key); //设置解密私钥
    return _decryp.decryptLong(obj);	//返回通过decryptLong方法解密后的结果
  }
};

RSA长文本分段加解密功能npm包地址点击这里
2、在其他页面进行调用加解密

import Utils from '@/utils/utils';//引入加解密工具文件名称自定,位置自定
//我的公钥私钥是通过请求从后端获取的,然后放在了sessionStorage中,不一定非要与我一样放sessionStorage,
//这个不错强制要求,能拿到就行
let PublicKey = JSON.parse(sessionStorage.getItem("rsaKey")).PublicKey //获取公钥
let PrivateKey = JSON.parse(sessionStorage.getItem("rsaKey")).PrivateKey //获取私钥

//页面中调用加密方法
Utils.RSAencrypt(PublicKey, JSON.stringify(data)) 
//这是调用加密方法返回参数 data为对象,需要先将其转化为JSON字符串

//页面中调用解密方法
JSON.parse(Utils.RSAdecrypt(PrivateKey, res.data))
//res.data为请求之后返回的加密数据

到这里,加解密就完全完成,下面说一些注意事项及沾一段我封装的请求request.js文件代码

如果你也是跟我一样公钥私钥是从接口中获取,那么你可能需要对拿到的数据使用;decodeURIComponent()这个方法进行url解码,因为在传输过程中数据可能会出现乱码问题;
同理进行加密前,你也有可能需要对数据进行一次解码操作后进行加密;
具体要不要进行解码,请查看数据有无出现乱码(如出现%)

下面我贴一段我的完整用法(可以直接跳过不看,以上代码已经完全展示了用法)

1、编写untils.js

/**
 * 工具类
 */
import Vue from "vue";
import JsEncrypt from "encryptlong";
export default {
  //第二步解密
  decrypt(word) {
    return decodeURIComponent(word.replace(/\+/g, '%20'))
  },

  //RSA加密
  RSAencrypt(key, obj) {
    console.log(obj)
    let encrypt = new JsEncrypt();
    encrypt.setPublicKey(key);
    return encrypt.encryptLong(obj);
  },
  //解密方法
  RSAdecrypt(key, obj) {
    let _decryp = new JsEncrypt();
    _decryp.setPrivateKey(key);
    return _decryp.decryptLong(obj);
  }
};

2、对JsEncrypt源文件(node-modules里面的jsencrypt.js)中加密方法统一对传入数据进行解码操作

 /**
     * 长文本加密
     * @param {string} string 待加密长文本
     * @returns {string} 加密后的base64编码
     */
    RSAKey.prototype.encryptLong = function (text) {
      text = encodeURIComponent(text) //对传入数据进行解码
      var _this = this;
      var maxLength = ((this.n.bitLength() + 7) >> 3) - 11;
      try {
        var ct_1 = "";
        if (text.length > maxLength) {
          var lt = text.match(/.{1,117}/g);
          lt.forEach(function (entry) {
            var t1 = _this.encrypt(entry);
            ct_1 += t1;
          });
          return hex2b64(ct_1);
        }
        var t = this.encrypt(text);
        var y = hex2b64(t);
        return y;
      } catch (ex) {
        return false;
      }
    };

3、封装request.js(大多数代码没什么用,如不想参考,请直接看post加密处)

import axios from "axios"; 
import Cookies from "js-cookie";
import store from "@/vuex/index";
import Utils from '@/utils/utils';

// 创建axios实例
const service = axios.create({
  timeout: 30000 // 请求超时时间
});

// request拦截器
service.interceptors.request.use(
  config => {
    //此处进行token等数据处理
    config.headers = {
      "Content-Type": "application/json;charset=UTF-8"
    };
    var token = Cookies.get("token");
    config.headers["Authorization"] = `Bearer ${token}`;
    return config;
  },
  error => {
    // Do something with request error
    Promise.reject(error);
  }
);
service.interceptors.response.use(
  response => {
    return response;
  },
  async error => {
    //判断请求是否超时,如果超时就返回登录页面
    var originalRequest = error.config;
    if (error.code == 'ECONNABORTED' && error.message.indexOf('timeout') != -1 && !originalRequest._retry) {
      this.$notify.error({
        title: '错误',
        message: "请求超时,请重新登录"
      });
      window.location.href = "/";
    }
    var task = new Promise(async (resolve, reject) => {
      await store.dispatch("getInfo", store.getters.token);
    }).catch(res => {
      //刷新token失败,神仙也救不了了,跳转到首页重新登录吧
      window.location.href = "/";
    });
    console.log(error);
    return Promise.reject("token过期");
  }
);

const AsyncAxios = function (url, type, data, that) {
  const base = store.getters.url;
  const getTimestamp = new Date().getTime();
  service.defaults.withCredentials = true;
  switch (type.toLowerCase()) {
    case "get":
      return service
        .get(`${base}${url}?timer=${getTimestamp}`, {
          params: data
        })
        .then(res => res.data);
//这里是对post请求进行统一加密解密
    case "post":
      let PublicKey = JSON.parse(sessionStorage.getItem("rsaKey")).PublicKey //获取公钥
      let PrivateKey = JSON.parse(sessionStorage.getItem("rsaKey")).PrivateKey //获取私钥
      return 	service.post(`${base}${url}`,Utils.RSAencrypt(PublicKey,JSON.stringify(data))
      ).then(res =>
      //此处我进行了两步解密,因为后端进行了两次加密操作
        JSON.parse(Utils.decrypt(Utils.RSAdecrypt(PrivateKey, res.data)))
      );
    case "put":
      return service.put(`${base}${url}`, data).then(res => res.data);
    case "delete":
      return service.delete(`${base}${url}`, data).then(res => res.data);
  }
};
const Axios = AsyncAxios;
export {
  Axios,
  AsyncAxios,
  AxiosUpload
};

4、封装axios请求方法api

//封装请求,方便进行统一管理
import {
  Axios
} from '@/utils/request'
export const logIn = (data) => Axios('/Login/Login', 'post', data)

5、在login.vue文件中调用接口

<template>
  <div class="login">
     <input class="input100" v-model="tel" type="text" name="LoginName" placeholder="手机号" />
     <input class="input100" v-model="verificationCode"  name="LoginPwd" placeholder="验证码" />
     <button type="button" class="login100-form-btn" @click="login">登陆</button>   
  </div>
</template>
import {logIn} from '@/api/login' //引入登录方法
export default {
  data() {
    return {
      verificationCode: '',
      tel: '',
    };
  },
	methods:{
		login(){
		   var data = {
		       Tel: this.tel,
		       VerificationCode: this.verificationCode
		       }
		   logIn(data).then(res => {
		       console.log(res)
		       }
		    }
		}
 }

至此RSA整个加密流程就全部讲完,工具文件可以完全照搬,但是请求封装请根据自己的实际情况来

  • 2
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值