Spring Boot3.3 项目数据库连接使用SM4国密加密算法进行脱敏配置

数据库 其他数据库
本文通过实际案例,详细介绍了如何在Spring Boot项目中使用SM4国密加密算法对数据库连接信息和用户数据进行加密与脱敏处理。我们展示了如何配置加密和解密操作,结合MyBatis-Plus实现数据库操作,并通过Thymeleaf和Bootstrap构建前端页面进行安全展示。

在现代企业级应用开发中,数据安全问题越来越受到重视。尤其是在处理敏感信息如数据库连接字符串、用户名、密码以及用户个人信息(如身份证号)时,如何在保证系统功能正常的前提下对这些敏感数据进行有效的保护,已经成为了开发人员必须面对的挑战。本文将通过一个实际的Spring Boot项目案例,介绍如何使用国密SM4加密算法对数据库连接中的url、username和password等信息进行加密处理,同时对用户表中的身份证号等敏感数据进行脱敏显示。

本文将详细展示如何配置Spring Boot项目以支持SM4加密算法,如何编写代码实现数据加密和解密,以及如何结合MyBatis-Plus实现数据库的CRUD操作,并在前端页面进行数据的展示与脱敏处理。我们将从配置文件的加密解密、后端服务的实现到前端视图的展示,逐步引导读者构建一个完整的、注重数据安全的Spring Boot项目。

运行效果:

图片图片

若想获取项目完整代码以及其他文章的项目源码,且在代码编写时遇到问题需要咨询交流,欢迎加入下方的知识星球。

表的DDL语句和插入数据的SQL语句

首先,我们需要创建一个user表,并插入10条用户数据。

-- 创建user表
CREATE TABLE user (
    id BIGINT PRIMARY KEY AUTO_INCREMENT,
    name VARCHAR(50) NOT NULL,
    id_number VARCHAR(18) NOT NULL,
    email VARCHAR(50) NOT NULL,
    phone VARCHAR(15) NOT NULL,
    address VARCHAR(100)
);

-- 插入10条用户数据
INSERT INTO user (name, id_number, email, phone, address) VALUES
('张三', '110101199001011234', 'zhangsan@example.com', '13800138000', '北京市朝阳区'),
('李四', '110102199002021234', 'lisi@example.com', '13800138001', '北京市海淀区'),
('王五', '110103199003031234', 'wangwu@example.com', '13800138002', '北京市西城区'),
('赵六', '110104199004041234', 'zhaoliu@example.com', '13800138003', '北京市东城区'),
('钱七', '110105199005051234', 'qianqi@example.com', '13800138004', '北京市丰台区'),
('孙八', '110106199006061234', 'sunba@example.com', '13800138005', '北京市石景山区'),
('周九', '110107199007071234', 'zhoujiu@example.com', '13800138006', '北京市通州区'),
('吴十', '110108199008081234', 'wushi@example.com', '13800138007', '北京市大兴区'),
('郑十一', '110109199009091234', 'zhengshiyi@example.com', '13800138008', '北京市昌平区'),
('王十二', '110110199010101234', 'wangshier@example.com', '13800138009', '北京市房山区');

引入SM4国密加密算法的依赖

在Spring Boot项目中,我们首先需要在pom.xml文件中引入必要的依赖。

<?xml versinotallow="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
	<modelVersion>4.0.0</modelVersion>
	<parent>
		<groupId>org.springframework.boot</groupId>
		<artifactId>spring-boot-starter-parent</artifactId>
		<version>3.3.3</version>
		<relativePath/> <!-- lookup parent from repository -->
	</parent>
	<groupId>com.icoderoad</groupId>
	<artifactId>SM4Encryption</artifactId>
	<version>0.0.1-SNAPSHOT</version>
	<name>SM4Encryption</name>
	<description>Demo project for Spring Boot</description>
	
	<properties>
		<java.version>17</java.version>
		<mybatis-spring.version>3.0.3</mybatis-spring.version>
		<mybatis-plus-boot-starter.version>3.5.7</mybatis-plus-boot-starter.version>
		<aliyun-java-sdk-cor.version>4.5.0</aliyun-java-sdk-cor.version>
		<bootstrap.version>5.1.3</bootstrap.version>
		<jquery.version>3.6.0</jquery.version>
	</properties>
	<dependencies>
		<!-- Spring Boot 依赖 -->
	    <dependency>
	        <groupId>org.springframework.boot</groupId>
	        <artifactId>spring-boot-starter-web</artifactId>
	    </dependency>
	   <!-- 数据库驱动依赖 -->
	    <dependency>
	        <groupId>com.mysql</groupId>
	        <artifactId>mysql-connector-j</artifactId>
	        <scope>runtime</scope>
	    </dependency>
	     <!-- MyBatis-Plus 依赖 -->
	    <dependency>
	        <groupId>com.baomidou</groupId>
	        <artifactId>mybatis-plus-boot-starter</artifactId>
	        <version>${mybatis-plus-boot-starter.version}</version>
	    </dependency>
	     <dependency>
	          <groupId>org.mybatis</groupId>
	          <artifactId>mybatis-spring</artifactId>
	          <version>${mybatis-spring.version}</version>
	      </dependency>
	    <!-- SM4 加密算法依赖 -->
	    <dependency>
	        <groupId>com.aliyun</groupId>
	        <artifactId>aliyun-java-sdk-core</artifactId>
	        <version>${aliyun-java-sdk-cor.version}</version>
	    </dependency>
	  	<dependency>
		        <groupId>org.projectlombok</groupId>
		        <artifactId>lombok</artifactId>
		        <optional>true</optional>
		    </dependency>
	    <!-- Thymeleaf 依赖 -->
	    <dependency>
	        <groupId>org.springframework.boot</groupId>
	        <artifactId>spring-boot-starter-thymeleaf</artifactId>
	    </dependency>
	    <!-- Bootstrap 和 jQuery -->
	    <dependency>
	        <groupId>org.webjars</groupId>
	        <artifactId>bootstrap</artifactId>
	        <version>${bootstrap.version}</version>
	    </dependency>
	    <dependency>
	        <groupId>org.webjars</groupId>
	        <artifactId>jquery</artifactId>
	        <version>${jquery.version}</version>
	    </dependency>

		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-test</artifactId>
			<scope>test</scope>
		</dependency>
	</dependencies>

	<build>
		<plugins>
			<plugin>
				<groupId>org.springframework.boot</groupId>
				<artifactId>spring-boot-maven-plugin</artifactId>
			</plugin>
		</plugins>
	</build>

</project>

配置SM4加密算法

在application.yml文件中,我们可以配置SM4加密的相关参数。

sm4:
  key: "37507d4cb936fdfb5dbb12a9a3983733" # SM4加密的密钥
  iv: "a7ae2a65d41fa7f98aec3579b8ec5a3c"   # SM4的初始化向量
  algorithm: "SM4"      # 加密算法
  mode: "CBC"           # 工作模式
  padding: "PKCS5Padding" # 填充模式

spring:
  datasource:
    url: ENC(sXjrlmJi+pBmt5ViI6uLAJ+teKmEfIPoJ5INkHEO2NtWcQ53zdATRyC4X+jru45oiaPjE74e+uLPgY/jHFy21iCVRnNpOFh5fHxn6NgF+04=)
    username: ENC(vB/qydt/80xm7Dxu48i/mA==)
    password: ENC(vB/qydt/80xm7Dxu48i/mA==)

实现SM4加密和解密工具类

package com.icoderoad.SM4Encryption.util;

import java.security.Security;
import java.util.Base64;

import javax.crypto.Cipher;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;

import org.bouncycastle.jce.provider.BouncyCastleProvider;
import org.springframework.util.Base64Utils;

public class SM4Util {
	
	static {
        Security.addProvider(new BouncyCastleProvider());
    }

    private static final String ALGORITHM_NAME = "SM4";
    private static final String ALGORITHM_NAME_CBC_PADDING = "SM4/CBC/PKCS5Padding";

    /**
     * SM4加密
     * @param plainText 明文
     * @param key 密钥
     * @param iv 向量
     * @return 加密后的密文
     */
    public static String encrypt(String plainText, String key, String iv) throws Exception {
        Cipher cipher = Cipher.getInstance(ALGORITHM_NAME_CBC_PADDING);
        SecretKeySpec keySpec = createKey(key);
        IvParameterSpec ivSpec = createIv(iv);
        cipher.init(Cipher.ENCRYPT_MODE, keySpec, ivSpec);
        byte[] encrypted = cipher.doFinal(plainText.getBytes());
        return Base64.getEncoder().encodeToString(encrypted);
    }

    /**
     * SM4解密
     * @param cipherText 密文
     * @param key 密钥
     * @param iv 向量
     * @return 解密后的明文
     */
    public static String decrypt(String cipherText, String key, String iv) throws Exception {
        Cipher cipher = Cipher.getInstance(ALGORITHM_NAME_CBC_PADDING);
        if (cipherText.startsWith("ENC(") && cipherText.endsWith(")")) {
        	cipherText = cipherText.substring(4, cipherText.length() - 1);
        }
       
        SecretKeySpec keySpec = createKey(key);
        IvParameterSpec ivSpec = createIv(iv);
        cipher.init(Cipher.DECRYPT_MODE, keySpec, ivSpec);
        byte[] decrypted = cipher.doFinal(Base64.getDecoder().decode(cipherText));
        return new String(decrypted);
    }
    
    private static SecretKeySpec createKey(String key) {
        byte[] keyBytes = key.getBytes();
        byte[] finalKey = new byte[16];
        System.arraycopy(keyBytes, 0, finalKey, 0, Math.min(keyBytes.length, 16));
        return new SecretKeySpec(finalKey, "SM4");
    }

    private static IvParameterSpec createIv(String iv) {
        byte[] ivBytes = iv.getBytes();
        byte[] finalIv = new byte[16];
        System.arraycopy(ivBytes, 0, finalIv, 0, Math.min(ivBytes.length, 16));
        return new IvParameterSpec(finalIv);
    }
}

在项目中应用SM4加密

生成加密后的值

为了生成加密后的url、username和password,可以使用以下测试代码来生成这些值。

package com.icoderoad.SM4Encryption;

import com.icoderoad.SM4Encryption.util.SM4Util;

public class SM4EncryptionTest {

	 public static void main(String[] args) throws Exception {
	        String url = "jdbc:mysql://localhost:3306/test?characterEncoding=utf8&useSSL=false";
	        String username = "root";
	        String password = "root";

	        String key = "37507d4cb936fdfb5dbb12a9a3983733";
	        String iv = "a7ae2a65d41fa7f98aec3579b8ec5a3c";

	        System.out.println("加密后的URL: " + SM4Util.encrypt(url, key, iv));
	        System.out.println("加密后的用户名: " + SM4Util.encrypt(username, key, iv));
	        System.out.println("加密后的密码: " + SM4Util.encrypt(password, key, iv));
	    }
	 
}

运行上述代码后,得到加密后的url、username和password,将这些值更新到application.yml中。

我们可以在Spring Boot项目中使用@Value注解将加密后的数据库密码解密并应用于数据源配置。

package com.icoderoad.SM4Encryption.conf;

import javax.sql.DataSource;

import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import com.icoderoad.SM4Encryption.util.SM4Util;
import com.zaxxer.hikari.HikariDataSource;

@Configuration
public class DataSourceConfig {

    @Value("${spring.datasource.url}")
    private String encryptedUrl;

    @Value("${spring.datasource.username}")
    private String encryptedUsername;

    @Value("${spring.datasource.password}")
    private String encryptedPassword;

    @Value("${sm4.key}")
    private String key;

    @Value("${sm4.iv}")
    private String iv;

    @Bean
    public DataSource dataSource() throws Exception {
        HikariDataSource dataSource = new HikariDataSource();
        dataSource.setJdbcUrl(SM4Util.decrypt(encryptedUrl, key, iv));
        dataSource.setUsername(SM4Util.decrypt(encryptedUsername, key, iv));
        dataSource.setPassword(SM4Util.decrypt(encryptedPassword, key, iv));
        return dataSource;
    }
}

User实体类

package com.icoderoad.SM4Encryption.entity;

import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.Data;

@Data
@TableName("user")
public class User {
    @TableId
    private Long id;
    private String name;
    private String idNumber;
    private String email;
    private String phone;
    private String address;
    
    @TableField(exist = false)
    private String sensitiveIdNumber;

    public String getSensitiveIdNumber() {
        return idNumber.replaceAll("(\\d{6})\\d{8}(\\d{4})", "$1****$2");
    }
}

UserMapper接口

package com.icoderoad.SM4Encryption.mapper;

import org.apache.ibatis.annotations.Mapper;

import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.icoderoad.SM4Encryption.entity.User;

@Mapper
public interface UserMapper extends BaseMapper<User> {
}

UserService接口

package com.icoderoad.SM4Encryption.service;

import com.baomidou.mybatisplus.extension.service.IService;
import com.icoderoad.SM4Encryption.entity.User;

public interface UserService extends IService<User> {
}

UserServiceImpl类

package com.icoderoad.SM4Encryption.service.impl;

import org.springframework.stereotype.Service;

import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.icoderoad.SM4Encryption.entity.User;
import com.icoderoad.SM4Encryption.mapper.UserMapper;
import com.icoderoad.SM4Encryption.service.UserService;

@Service
public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements UserService {
}

我们需要创建一个控制器类来处理前端视图页面的请求,并将数据传递给视图页面进行展示。

UserController类

package com.icoderoad.SM4Encryption.controller;

import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;

import com.icoderoad.SM4Encryption.entity.User;
import com.icoderoad.SM4Encryption.service.UserService;

@Controller
public class UserController {

    @Autowired
    private UserService userService;

    @GetMapping("/")
    public String listUsers(Model model) {
        List<User> users = userService.list();
        model.addAttribute("users", users);
        return "index";
    }
}

前端展示页面与数据脱敏

前端页面使用Thymeleaf模板引擎,并结合Bootstrap进行数据展示和脱敏处理。

在 src/main/resources/templates/index.html 中创建一个简单的前端页面:

<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="UTF-8">
    <title>用户数据</title>
    <link href="/webjars/bootstrap/css/bootstrap.min.css" rel="stylesheet">
    <script src="/webjars/jquery/jquery.min.js"></script>
    <script src="/webjars/bootstrap/js/bootstrap.bundle.min.js"></script>
     <style>
     	.container{
     		text-align: center;
     	}
         thead th {
             background-color: #007bff;
             color: white;
         }
         tbody tr:nth-child(even) {
             background-color: #f8f9fa;
         }
         .table {
         	margin: 20px auto;
         	width: 80%;
         }
         tr{
         	height: 30px;
         }
     </style>
</head>
<body>
    <div class="container  mt-5">
        <h2>用户数据</h2>
        <table class="table table-bordered">
            <thead>
                <tr>
                    <th>ID</th>
                    <th>姓名</th>
                    <th>身份证号</th>
                    <th>邮箱</th>
                    <th>电话</th>
                    <th>地址</th>
                </tr>
            </thead>
            <tbody>
                <tr th:each="user : ${users}">
                    <td th:text="${user.id}"></td>
                    <td th:text="${user.name}"></td>
                    <td th:text="${user.sensitiveIdNumber}"></td>
                    <td th:text="${user.email}"></td>
                    <td th:text="${user.phone}"></td>
                    <td th:text="${user.address}"></td>
                </tr>
            </tbody>
        </table>
    </div>
</body>
</html>

总结

本文通过实际案例,详细介绍了如何在Spring Boot项目中使用SM4国密加密算法对数据库连接信息和用户数据进行加密与脱敏处理。我们展示了如何配置加密和解密操作,结合MyBatis-Plus实现数据库操作,并通过Thymeleaf和Bootstrap构建前端页面进行安全展示。

通过本文,大家可以掌握如何在Spring Boot中集成加密算法,并将其应用于实际项目中,提升数据安全性。希望本文为大家在处理敏感信息时提供了实用的指导,帮助构建更安全的企业级应用程序。

责任编辑:武晓燕 来源: 路条编程
相关推荐

2023-06-26 00:30:51

2024-08-26 09:15:55

RedissonMyBatisSpring

2024-08-29 08:23:22

EasyOCRSpring文字识别

2024-09-02 08:12:32

Spring策略MyBatis

2024-10-14 13:26:42

2020-10-26 19:20:08

Linux国密算法加密

2015-02-26 09:21:42

Jenkins数据库加密

2023-10-16 19:05:20

2023-08-01 07:24:05

2015-06-23 11:11:55

2009-08-13 18:12:11

C#数据加密

2013-10-17 13:20:34

2017-12-27 15:16:35

Spring BootFlyway数据库

2009-08-04 11:08:33

ASP.NET数据加密

2024-10-15 10:38:32

2011-12-28 13:14:39

2012-09-25 09:19:26

Spring数据库双数据库

2024-01-10 08:17:50

HikariCP数据库Spring

2021-11-22 23:20:01

加密算法架构

2023-08-02 07:27:53

点赞
收藏

51CTO技术栈公众号