AES对称和RSA非对称加密登录接口参数

使用RSA非对称加密+AES对称加密

  1. 加密类型

    • RSA:是一种非对称加密算法。它使用一对密钥(公钥和私钥),其中公钥可以公开给任何人,用于加密数据;而私钥需要保密,用于解密数据。
    • AES:是一种对称加密算法。它使用同一个密钥进行加密和解密操作,这意味着在加密和解密过程中,通讯双方必须共享相同的密钥。这种情况下,密钥的安全传输和管理成为了一个关键问题。
  2. 性能与效率

    • RSA:RSA的加密和解密速度较慢,不适用于大量数据的直接加密,更适合加密少量数据,如加密会话密钥或者数字签名等。
    • AES:AES加密速度快,适合加密大量的数据。

由于AES秘钥放在前端不安全,所以采用如下思路

  • 后台生成RSA公钥和私钥,公钥给前端
  • 前端生成AES秘钥,并加密data
  • 前端使用RSA公钥加密AES秘钥,
  • 前端传输给后台加密的data和加密的AES和公钥
  • 后台使用对应RSA私钥解密得到AES秘钥,再用AES秘钥解密data

使用 crypto-js 的AES方式对接口参数进行加密

  • 安装引入
npm install crypto-js
import CryptoJS from 'crypto-js'; //  使用CryptoJS库进行加密
  • 定义加密函数
let key = '5F6B2AK33DASD1235E74C231B47AC8F6' //AES秘钥
// 定义你的加密函数(需要加密的data,AES秘钥)
function encryptData(data,key) {
  // 这样写的加密后在线工具可以正常解密,但是后台无法解密
  // return CryptoJS.AES.encrypt(JSON.stringify(data), 'sQPoC/1do9BZMkg8I5c09A==').toString();

  const _key = CryptoJS.enc.Utf8.parse(key) //将秘钥转换成Utf8字节数组
  // const iv = CryptoJS.enc.Utf8.parse(key.substr(0, 16))
  //加密
  const encrypt = CryptoJS.AES.encrypt(JSON.stringify(data), _key, {
    // iv: iv,
    mode: CryptoJS.mode.ECB,
    padding: CryptoJS.pad.Pkcs7
  })
  return encrypt.toString()
}

RSA加解密——jsencrypt库

npm install jsencrypt --save
// 或者cdn引入
<script src="https://cdnjs.cloudflare.com/ajax/libs/jsencrypt/3.2.1/jsencrypt.min.js"></script>
  • 加密方法
// 需要加密的data,RSA公钥
function rsaEncrypt(data,publicKey) {
  var encryptor = new JSEncrypt();
  // 假设你已经获取到了后端提供的公钥字符串(key是Base64编码的公钥)
  encryptor.setPublicKey(publicKey);

  //使用公钥加密 
  return encryptor.encrypt(data);
}

  • 解密方法
// 需要加密的data,RSA私钥
function decrypt(data,privateKey) {
   const encryptor = new JSEncrypt()   
   encryptor.setPrivateKey(privateKey) // 设置私钥
   return encryptor.decrypt(data) // 对数据进行解密
}

实际代码逻辑

登录页面路由拦截获取RSA公钥,存储在本地

beforeRouteEnter(to, from, next) {
    // 假设有个 API 方法 
    getRsaPulicKey().then(response => { 
      console.log(response.data.publicKey)
      localStorage.setItem('PublicKey', response.data.publicKey);
      next();
    }).catch(error => {
      // 如果请求失败,可以重定向到错误页面或者其他操作
      next('/login');
    });
  },

在request.js文件进行修改接口参数的修改

  • 定义随机AES私钥
/**
 * @returns 生成不重复的随机序列号  '60a2cd4faec2474ca6ee43aac3b0bc1d'
 * 32位  16进制
 */
function getUUID() {
  var d = new Date().getTime();
  if (window.performance && typeof window.performance.now === "function") {
    d += performance.now(); //use high-precision timer if available
  }
  var uuid = "xxxxxxxxxxxx4xxxyxxxxxxxxxxxxxxx".replace(/[xy]/g, function (c) {
    var r = (d + Math.random() * 16) % 16 | 0;
    d = Math.floor(d / 16);
    return (c == "x" ? r : (r & 0x3) | 0x8).toString(16);
  });
  return uuid;
}
// 定义AES加密函数 
let AESKey = getUUID()
  • 定义AES加密data函数和RSA加密私钥函数
// AES加密数据data
function aesEncrypt(data) {
  // 这样写的加密后在线工具可以正常解密,但是后台无法解密
  // return CryptoJS.AES.encrypt(JSON.stringify(data), 'sQPoC/1do9BZMkg8I5c09A==').toString();

  const _key = CryptoJS.enc.Utf8.parse(AESKey) //将秘钥转换成Utf8字节数组
  // const iv = CryptoJS.enc.Utf8.parse(key.substr(0, 16))
  //加密
  const encrypt = CryptoJS.AES.encrypt(JSON.stringify(data), _key, {
    // iv: iv,
    mode: CryptoJS.mode.ECB,
    padding: CryptoJS.pad.Pkcs7
  })
  return encrypt.toString()
}

//定义RSA加密函数,,对AES秘钥加密
function rsaEncrypt(publicKey) {
  var encryptor = new JSEncrypt();
  // 假设你已经获取到了后端提供的公钥字符串(key是Base64编码的公钥)
  encryptor.setPublicKey(publicKey);

  //使用公钥加密
  var plaintext = AESKey;
  return encryptor.encrypt(plaintext);
}
  • request拦截器判断是登录接口修改其data
// request拦截器
service.interceptors.request.use(config => {
  console.log('request11', config, config.data)
  if (config.url == "/auth/login") { 
    let PublicKey = ''
    if (!localStorage.getItem("PublicKey")) {
      Message({
        message: '未获取到公钥',
        type: 'error',
      })
      return
    } else {
      PublicKey = localStorage.getItem("PublicKey")
    }
    config.data = {
      data: aesEncrypt(config.data), //AES加密后的data
      aesKey: rsaEncrypt(PublicKey), //RSA加密后的aes私钥
      publicKey: PublicKey //RSA公钥
    };
  }
  • 5
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

小曲曲

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值