SpringBoot集成数据传输加密

本文涉及的产品
数据传输服务 DTS,数据迁移 small 3个月
推荐场景:
MySQL数据库上云
数据传输服务 DTS,数据同步 1个月
数据传输服务 DTS,同步至 ClickHouse 1个月
简介: 近期在对开发框架安全策略方面进行升级优化,提供一些通用场景的解决方案,本文针对前后端数据传输加密进行简单的分享,处理流程设计如下图所示,本加密方法对原有项目兼容性较好,只需要更换封装好的加密Ajax请求方法,后端统一拦截判断是否需要解密即可

前言

近期在对开发框架安全策略方面进行升级优化,提供一些通用场景的解决方案,本文针对前后端数据传输加密进行简单的分享,处理流程设计如下图所示,本加密方法对原有项目兼容性较好,只需要更换封装好的加密Ajax请求方法,后端统一拦截判断是否需要解密即可

生成DESKey

生成的DES加密密钥一定是8的整数倍的位数

function getRandomStr() {
   
   
    let str = ""
    let array = [
        "0",
        "1",
        "2",
        "3",
        "4",
        "5",
        "6",
        "7",
        "8",
        "9",
        "a",
        "b",
        "c",
        "d",
        "e",
        "f",
        "g",
        "h",
        "i",
        "j",
        "k",
        "l",
        "m",
        "n",
        "o",
        "p",
        "q",
        "r",
        "s",
        "t",
        "u",
        "v",
        "w",
        "x",
        "y",
        "z",
        "A",
        "B",
        "C",
        "D",
        "E",
        "F",
        "G",
        "H",
        "I",
        "J",
        "K",
        "L",
        "M",
        "N",
        "O",
        "P",
        "Q",
        "R",
        "S",
        "T",
        "U",
        "V",
        "W",
        "X",
        "Y",
        "Z",
    ];
    for (let i = 0; i < 8; i++) {
   
   
        str +=  array[Math.round(Math.random() * (array.length - 1))];
    }
    return str;
}

生成RSA密钥对

RSA密钥对有很多种格式,因为需要和前端算法库互联互通,这里选择的是1024位,Padding方式为PKSC1

    public static Map<String, String> createKeysPKSC1(int keySize) {
        // map装载公钥和私钥
        Map<String, String> keyPairMap = new HashMap<String, String>();
        try {
            Security.addProvider(new org.bouncycastle.jce.provider.BouncyCastleProvider());
            SecureRandom random = new SecureRandom();
            KeyPairGenerator generator = KeyPairGenerator.getInstance("RSA", "BC");
            generator.initialize(keySize, random);
            KeyPair keyPair = generator.generateKeyPair();
            RSAPublicKey publicKey = (RSAPublicKey) keyPair.getPublic();
            RSAPrivateKey privateKey = (RSAPrivateKey) keyPair.getPrivate();
            String publicKeyStr = new String(Base64.encodeBase64(publicKey.getEncoded()));
            String privateKeyStr = new String(Base64.encodeBase64(privateKey.getEncoded()));
            keyPairMap.put("publicKey", publicKeyStr);
            keyPairMap.put("privateKey", privateKeyStr);
        } catch (Exception e) {
            e.printStackTrace();
        }
        // 返回map
        return keyPairMap;
    }

前端DES加密

引入crypto.js第三方库

    function encryptByDES(message, key) {
   
   
        var keyHex = CryptoJS.enc.Utf8.parse(key);
        var encrypted = CryptoJS.DES.encrypt(message, keyHex, {
   
   
            mode: CryptoJS.mode.ECB,
            padding: CryptoJS.pad.Pkcs7
        });
        return encrypted.toString();
    }

前端RSA加密

引入jsencrypt,js第三方库

    function encryptByRSA(data, publicKey) {
   
   
        var encryptor = new JSEncrypt()
        encryptor.setPublicKey(publicKey)
        return encryptor.encrypt(data);;
    }

后端RSA解密

    public static String decryptPKSC1(String data, String privateKeyStr) {
   
   
        try {
   
   
            Security.addProvider(new org.bouncycastle.jce.provider.BouncyCastleProvider());
            Cipher cipher = Cipher.getInstance("RSA/None/PKCS1Padding", "BC");
            RSAPrivateKey privateKey = getPrivateKeyPKSC1(privateKeyStr);
            cipher.init(Cipher.DECRYPT_MODE, privateKey);
            return new String(rsaSplitCodec(cipher, Cipher.DECRYPT_MODE, Base64.decodeBase64(data), privateKey.getModulus().bitLength()), CHARSET);
        } catch (Exception e) {
   
   
            throw new RuntimeException("解密字符串[" + data + "]时遇到异常", e);
        }
    }

后端DES解密

    public static String decrypt(String data, String key) throws IOException,
            Exception {
   
   
        if (data == null)
            return null;
        BASE64Decoder decoder = new BASE64Decoder();
        byte[] buf = decoder.decodeBuffer(data);
        byte[] bt = decrypt(buf, key.getBytes("UTF-8"));
        return new String(bt, "UTF-8");
    }

后端自定义拦截器

public class XSSFilter implements Filter, Ordered {
   
   

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

    @Override
    public void destroy() {
   
   
    }

    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
   
   
        String contentType = request.getContentType();
        if (StringUtils.isNotBlank(contentType) && contentType.contains("application/json")) {
   
   
            XSSBodyRequestWrapper xssBodyRequestWrapper = new XSSBodyRequestWrapper((HttpServletRequest) request);
            chain.doFilter(xssBodyRequestWrapper, response);
        } else {
   
   
            chain.doFilter(request, response);
        }
    }

    @Override
    public int getOrder() {
   
   
        return 9;
    }
}
public class XSSBodyRequestWrapper extends HttpServletRequestWrapper {
   
   

    private String body;

    public XSSBodyRequestWrapper(HttpServletRequest request) {
   
   
        super(request);
        try{
   
   
            body = XSSScriptUtil.handleString(CommonUtil.getBodyString(request));
            String encrypt = request.getHeader("encrypt");
            if (!StringUtil.isEmpty(encrypt)) {
   
   
                String privateKey = RSAEncryptUtil.getSystemDefaultRSAPrivateKey();
                String desEncryptStr = RSAEncryptUtil.decryptPKSC1(encrypt, privateKey);
                JSONObject obj = JSONObject.parseObject(body);
                String encryptParam = obj.getString("encryptParam");
                body = DESEncryptUtil.decrypt(encryptParam, desEncryptStr);
            }
        }catch (Exception e){
   
   
            e.printStackTrace();
        }
    }

    @Override
    public BufferedReader getReader() throws IOException {
   
   
        return new BufferedReader(new InputStreamReader(getInputStream()));
    }

    @Override
    public ServletInputStream getInputStream() throws IOException {
   
   

        final ByteArrayInputStream bais = new ByteArrayInputStream(body.getBytes(Charset.forName("UTF-8")));

        return new ServletInputStream() {
   
   

            @Override
            public int read() throws IOException {
   
   
                return bais.read();
            }

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

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

            @Override
            public void setReadListener(ReadListener readListener) {
   
   

            }
        };
    }

}
目录
相关文章
|
8月前
|
安全 Java Apache
微服务——SpringBoot使用归纳——Spring Boot中集成 Shiro——Shiro 身份和权限认证
本文介绍了 Apache Shiro 的身份认证与权限认证机制。在身份认证部分,分析了 Shiro 的认证流程,包括应用程序调用 `Subject.login(token)` 方法、SecurityManager 接管认证以及通过 Realm 进行具体的安全验证。权限认证部分阐述了权限(permission)、角色(role)和用户(user)三者的关系,其中用户可拥有多个角色,角色则对应不同的权限组合,例如普通用户仅能查看或添加信息,而管理员可执行所有操作。
445 0
|
8月前
|
安全 Java 数据安全/隐私保护
微服务——SpringBoot使用归纳——Spring Boot中集成 Shiro——Shiro 三大核心组件
本课程介绍如何在Spring Boot中集成Shiro框架,主要讲解Shiro的认证与授权功能。Shiro是一个简单易用的Java安全框架,用于认证、授权、加密和会话管理等。其核心组件包括Subject(认证主体)、SecurityManager(安全管理员)和Realm(域)。Subject负责身份认证,包含Principals(身份)和Credentials(凭证);SecurityManager是架构核心,协调内部组件运作;Realm则是连接Shiro与应用数据的桥梁,用于访问用户账户及权限信息。通过学习,您将掌握Shiro的基本原理及其在项目中的应用。
330 0
|
3月前
|
安全 算法 Java
在Spring Boot中应用Jasypt以加密配置信息。
通过以上步骤,可以在Spring Boot应用中有效地利用Jasypt对配置信息进行加密,这样即使配置文件被泄露,其中的敏感信息也不会直接暴露给攻击者。这是一种在不牺牲操作复杂度的情况下提升应用安全性的简便方法。
981 10
|
5月前
|
前端开发
SpringBoot2.3.1集成Knife4j接口文档
SpringBoot2.3.1集成Knife4j接口文档
562 44
|
4月前
|
JSON 分布式计算 大数据
springboot项目集成大数据第三方dolphinscheduler调度器
springboot项目集成大数据第三方dolphinscheduler调度器
275 3
|
4月前
|
缓存 JSON 前端开发
第07课:Spring Boot集成Thymeleaf模板引擎
第07课:Spring Boot集成Thymeleaf模板引擎
524 0
第07课:Spring Boot集成Thymeleaf模板引擎
|
4月前
|
Java 关系型数据库 MySQL
springboot项目集成dolphinscheduler调度器 实现datax数据同步任务
springboot项目集成dolphinscheduler调度器 实现datax数据同步任务
571 2
|
4月前
|
分布式计算 Java 大数据
springboot项目集成dolphinscheduler调度器 可拖拽spark任务管理
springboot项目集成dolphinscheduler调度器 可拖拽spark任务管理
292 2
|
4月前
|
人工智能 安全 Java
Spring Boot yml 配置敏感信息加密
本文介绍了如何在 Spring Boot 项目中使用 Jasypt 实现配置文件加密,包含添加依赖、配置密钥、生成加密值、在配置中使用加密值及验证步骤,并提供了注意事项,确保敏感信息的安全管理。
1130 1

热门文章

最新文章