uni-app和springboot完成前端后端对称加密解密流程

这篇具有很好参考价值的文章主要介绍了uni-app和springboot完成前端后端对称加密解密流程。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

概述

  • 使用对称加密的方式实现。
  • 前端基于crypto-js。
  • uni-app框架中是在uni.request的基础上,在拦截器中处理的。
  • springboot在Filter中完成解密工作。

uni-app

  1. 项目中引入crypto-js。
npm install crypto-js
  1. 加密方法
const SECRET_KEY = CryptoJS.enc.Utf8.parse("1234123412341234");

function encrypt (msg) {
	const dataHex = CryptoJS.enc.Utf8.parse(msg);
	const encrypted = CryptoJS.AES.encrypt(dataHex, SECRET_KEY, {
	  mode: CryptoJS.mode.ECB,
	  padding: CryptoJS.pad.Pkcs7
	});
	return encrypted.ciphertext.toString(CryptoJS.enc.Base64);
}
  1. 解密方法
function decrypt(msg) {
	const encryptedHexStr = CryptoJS.enc.Hex.parse(msg);
	const str = CryptoJS.enc.Base64.stringify(encryptedHexStr);
	const decrypt = CryptoJS.AES.decrypt(str, SECRET_KEY, {
	    mode: CryptoJS.mode.ECB,
	    padding: CryptoJS.pad.Pkcs7
	});
	return decrypt.toString(CryptoJS.enc.Utf8);
}
  1. request拦截器
uni.addInterceptor('request', {
  invoke(args) {
	let plaintext = JSON.stringify(args.data);
	plaintext = encodeURIComponent(plaintext);
	const textArray = [];
	while(plaintext.length > 15) {
		textArray.push(plaintext.substring(0, 16));
		plaintext = plaintext.substring(16);
	}
	textArray.push(plaintext);
	
	const encryptParamArray = [];
	textArray.forEach(item => {
		encryptParamArray.push(btoa(encrypt(item)));
	})
	
	args.data = {"encryptParams": encryptParamArray};
  },
  success(args) {
  }, 
  fail(err) {
  }, 
  complete(res) {
  }
});
备注
  • 使用encodeURIComponent方法是为了处理 字符“+”,这个对应java解密的时候存在问题。
  • 该模式默认解密长度出限制在16个字符中,所以需要将待加密的信息分解成单个字符长度小于16的字符组成数组。

Springboot

  1. DecryptFilter,解密拦截器
import cn.hutool.json.JSONUtil;
import org.apache.commons.codec.binary.Base64;
import org.springframework.http.HttpMethod;

import javax.crypto.Cipher;
import javax.crypto.spec.SecretKeySpec;
import javax.servlet.*;
import javax.servlet.annotation.WebFilter;
import javax.servlet.http.HttpServletRequest;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.URLDecoder;
import java.nio.charset.StandardCharsets;

@WebFilter(urlPatterns = "/*") // 过滤所有请求
public class DecryptFilter implements Filter {

    private String word;
    public DecryptFilter(String word) {
        this.word = word;
    }

    @Override
    public void init(FilterConfig filterConfig) throws ServletException {

    }

    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
        HttpServletRequest httpRequest = (HttpServletRequest) servletRequest;

        if (HttpMethod.OPTIONS.matches(httpRequest.getMethod())) {
            filterChain.doFilter(httpRequest, servletResponse);
            return;
        }
        String encryptedData = "";
        if (httpRequest.getHeader("Content-Type").contains("x-www-form-urlencoded")) {
            // 获取请求参数或请求体中的加密数据
            encryptedData = httpRequest.getParameter("encryptParams");

        } else if (httpRequest.getHeader("Content-Type").contains("json")) {

            StringBuilder stringBuilder = new StringBuilder();
            try (InputStream inputStream = httpRequest.getInputStream();
                 BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(inputStream, StandardCharsets.UTF_8))) {
                String line;
                while ((line = bufferedReader.readLine()) != null) {
                    stringBuilder.append(line);
                }
            }

            encryptedData = JSONUtil.parseObj(stringBuilder.toString()).get("encryptParams").toString();
            encryptedData = encryptedData.replaceAll("[\\[\\]\"]", "");
        }

        String[] ciphertextArray = encryptedData.split(",");

        // 解密操作,例如使用AES解密
        String decryptedData = "";
        try {
            decryptedData = decrypt(ciphertextArray);
        } catch (Exception e) {
            throw new RuntimeException("解密失败!", e);
        }

        // 重构ServletRequest,将解密后的数据设置到新的ServletRequest中
        ServletRequest modifiedRequest = new BodyRewritingRequestWrapper(httpRequest, decryptedData);

        // 继续执行过滤器链
        filterChain.doFilter(modifiedRequest, servletResponse);
    }

    @Override
    public void destroy() {

    }

    private String decrypt(String[] encryptedTextArray) throws Exception {
        StringBuilder paramsJson = new StringBuilder("");

        // 创建解密器
        Cipher cipher = Cipher.getInstance("AES/ECB/PKCS5Padding");
        byte[] keyBytes = word.getBytes(StandardCharsets.UTF_8);
        SecretKeySpec keySpec = new SecretKeySpec(keyBytes, "AES");
        cipher.init(Cipher.DECRYPT_MODE, keySpec);

        for (String ciphertext : encryptedTextArray) {
            byte[] decode = java.util.Base64.getDecoder().decode(ciphertext);
            byte[] encryptedBytes = Base64.decodeBase64(decode);
            byte[] decryptedBytes = cipher.doFinal(encryptedBytes);
            paramsJson.append(new String(decryptedBytes, StandardCharsets.UTF_8));
        }

        return URLDecoder.decode(paramsJson.toString(), "UTF-8");
    }
}
  1. BodyRewritingRequestWrapper,重写的ServletRequest对相关
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;

import javax.servlet.ReadListener;
import javax.servlet.ServletInputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletRequestWrapper;
import java.io.BufferedReader;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.HashMap;
import java.util.Map;

public class BodyRewritingRequestWrapper extends HttpServletRequestWrapper {
    private String body;

    private JSONObject map;

    public BodyRewritingRequestWrapper(HttpServletRequest request, String body) {
        super(request);
        this.body = body;
        this.map = JSONUtil.parseObj(body);
    }

    @Override
    public String getParameter(String name) {
        if (map.containsKey(name)) {
            return map.get(name).toString();
        }

        return super.getParameter(name);
    }

    @Override
    public Map<String, String[]> getParameterMap() {
        Map<String, String[]> originalParameters = super.getParameterMap();
        Map<String, String[]> rewriteMap = new HashMap<>(originalParameters);
        map.forEach((key, value) -> rewriteMap.put(key, new String[]{value.toString()}));
        return rewriteMap;
    }

    @Override
    public ServletInputStream getInputStream() throws IOException {
        final ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(body.getBytes());
        return new ServletInputStream() {
            public int read() throws IOException {
                return byteArrayInputStream.read();
            }

            @Override
            public boolean isFinished() {
                return false;
            }

            @Override
            public boolean isReady() {
                return true;
            }

            @Override
            public void setReadListener(ReadListener readListener) {

            }
        };
    }

    @Override
    public BufferedReader getReader() throws IOException {
        return new BufferedReader(new InputStreamReader(this.getInputStream()));
    }
}
  1. 注册拦截器
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.web.servlet.FilterRegistrationBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.HttpMethod;
import org.springframework.web.cors.CorsConfiguration;
import org.springframework.web.cors.UrlBasedCorsConfigurationSource;
import org.springframework.web.filter.CorsFilter;

@Configuration
public class WebConfig {

    @Value("${decrypt.word}")
    private String word;

    @Bean
    public FilterRegistrationBean<DecryptFilter> myFilterRegistration() {
        FilterRegistrationBean<DecryptFilter> registration = new FilterRegistrationBean<>();
        registration.setFilter(new DecryptFilter(word));
        registration.addUrlPatterns("/*");
        registration.setName("decryptFilter");
        registration.setOrder(1);  // 设置过滤器的顺序,根据实际需求设置
        return registration;
    }
}

文章来源地址https://www.toymoban.com/news/detail-637083.html

到了这里,关于uni-app和springboot完成前端后端对称加密解密流程的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 后端C# .net 前端uni-app 集成SignalR做即时通讯

            后端集成SignalR比较简单,首先要在解决方案中依赖几个SignalR的库,SignalR的库就是做即时通讯的主要库,我们建立连接、收发信息都需要用这个库来进行。         除了这几个库以外,还要还有几个依赖库要一并依赖进来。         Owin库的作用主要是为了在

    2024年04月17日
    浏览(23)
  • 微信小程序外卖跑腿点餐(订餐)系统(uni-app+SpringBoot后端+Vue管理端技术实现)

    自从计算机发展开始,计算机软硬件相关技术的发展速度越来越快,在信息化高速发展的今天,计算机应用技术似乎已经应用到了各个领域。 在餐饮行业,除了外卖以外就是到店里就餐,在店里就餐如果需要等待点餐的话,用户的体验度就会急剧下降,很多餐饮店也开始开发

    2024年04月11日
    浏览(33)
  • SpringBoot+Vue 后端输出加密,前端请求统一解密

    针对客户对数据交互过程中的加密要求,防止直接的数据爬取,对前后端数据请求时的返回数据进行数据的加密。实用性嘛,也就那样了,代码可直接适配Ruoyi SpringBoot+vue项目,具体加密方式和处理仅供参考! 前端 request.js des.js 后端java

    2024年02月09日
    浏览(30)
  • uni-app:请求后端数据uni.request

     完整代码: 核心 使用的方法 uni.request({...});  与接口相连接的路径 注:这里标红的部分为全局变量 例如: url:\\\'https://域名/api/Produce/select_employee\\\'(表示在使用该域名下的api中的Produce文件的select_employee方法) url: getApp().globalData.position + \\\'Produce/select_employee\\\', 传入数据到后端 

    2024年02月16日
    浏览(29)
  • uni-app 小程序使用腾讯地图完成搜索功能

    前言 使用uni-app开发小程序时候使用腾讯地图原生SDK是,要把原生写法转成vue写法在这记录一下。 我们需要注意的是使用高德地图时我们不仅要引入SDK,还要再uni-app中配置允许使用。 由于uni-app内置地图就是腾讯,所以获取位置的api,uni.getLocation坐标不用转换,直接使用。

    2024年02月08日
    浏览(30)
  • 三分钟完成小程序 uni-app、网站接入chatgpt实现聊天效果

    1.实现后台接口 注册laf云开发账号 https://laf.dev/ 注册一个应用后进入这个页面: 下载依赖 chatgpt 配置apiKey 写send函数 配置你的apiKey 2.uni-app小程序代码中 //封装cloud 发送消息方法 微信小程序中使用 3.实现效果 在这里插入图片描述

    2024年02月11日
    浏览(29)
  • uni-app -- - - - 小程序如何向后端发送Form Data格式的数据

    接口请 求方式 传参方式 ,肯定不是一成不变的,当遇到如题需求的时候,要知道, 小程序是没有FormData对象 的,那么该怎么操作呢??? 直接上代码: 效果如图: 如上所示,这样写起来功能实现了,但是看起来这代码太不美观了 效果如图: 参考文章: 使用wx.request发送

    2024年02月08日
    浏览(28)
  • 前端-vscode中开发uni-app

    node -v npm install @vue/ cli@4.5.15 -g 指定版本号:4.5.15 在自己电脑目录下创建项目: demo02是自己项目名字 在D/AllCode/vs_vue2_uniapp目录下执行一下命令: vue create -p dcloudio/uni-preset-vue demo02 要想在vscode执行npm命令 我们打开pages.json和manifest.json,发现会报红,这是因为在json中是不能写注

    2024年01月18日
    浏览(50)
  • UNI-APP 人脸识别分析及实现(前端)

    实现流程: 1、打开摄像头——自动读取照片——传输给后端——后端交由第三发或自主开发来识别——返回结果(相识度比) 2、打开摄像头——自动读取视频——传输给后端——后端通过解析视频,截取图片交由第三发或自主开发来识别——返回结果(相识度比) 通过分

    2023年04月08日
    浏览(28)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包