本文将详细展示如何配置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文件中引入必要的依赖。
4.0.0
org.springframework.boot
spring-boot-starter-parent
3.3.3
com.icoderoad
SM4Encryption
0.0.1-SNAPSHOT
SM4Encryption
Demo project for Spring Boot
17
3.0.3
3.5.7
4.5.0
5.1.3
3.6.0
org.springframework.boot
spring-boot-starter-web
com.mysql
mysql-connector-j
runtime
com.baomidou
mybatis-plus-boot-starter
${mybatis-plus-boot-starter.version}
org.mybatis
mybatis-spring
${mybatis-spring.version}
com.aliyun
aliyun-java-sdk-core
${aliyun-java-sdk-cor.version}
org.projectlombok
lombok
true
org.springframework.boot
spring-boot-starter-thymeleaf
org.webjars
bootstrap
${bootstrap.version}
org.webjars
jquery
${jquery.version}
org.springframework.boot
spring-boot-starter-test
test
org.springframework.boot
spring-boot-maven-plugin
配置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";
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);
}
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 {
}
UserService接口
package com.icoderoad.SM4Encryption.service;
import com.baomidou.mybatisplus.extension.service.IService;
import com.icoderoad.SM4Encryption.entity.User;
public interface UserService extends IService {
}
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 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 users = userService.list();
model.addAttribute("users", users);
return "index";
}
}
前端展示页面与数据脱敏
前端页面使用Thymeleaf模板引擎,并结合Bootstrap进行数据展示和脱敏处理。
在 src/main/resources/templates/index.html 中创建一个简单的前端页面:
用户数据
用户数据
ID
姓名
身份证号
邮箱
电话
地址
总结
本文通过实际案例,详细介绍了如何在Spring Boot项目中使用SM4国密加密算法对数据库连接信息和用户数据进行加密与脱敏处理。我们展示了如何配置加密和解密操作,结合MyBatis-Plus实现数据库操作,并通过Thymeleaf和Bootstrap构建前端页面进行安全展示。
通过本文,大家可以掌握如何在Spring Boot中集成加密算法,并将其应用于实际项目中,提升数据安全性。希望本文为大家在处理敏感信息时提供了实用的指导,帮助构建更安全的企业级应用程序。