在数据库中经常会保存一下用户的敏感数据信息,例如身份证号、手机号、用户密码等。如果这些信息以明文的方式保存,一旦数据被恶意获取到就会导致这这些敏感信息的泄露。

第一步:依赖

除了正常的mybatis和springboot开发依赖包之外,需要额外加入以下包

<!-- Hutool 加密解密 -->
<dependency>
<groupId>cn.hutool</groupId>
<artifactId>hutool-all</artifactId>
<version>5.6.5</version>
</dependency>

第二步:配置文件

我使用的是mybatis-plus,如果使用的是mybatis,对应的将mybatis-plus修改为mybatis即可。

这个路径即使你下面书写的Typehandler的包路径

mybatis-plus:
type-handlers-package: com.smile.project.pass.utils

第三步:

编写一个实体类,凡是此实体类的数据都表示需要加解密

/**
* 编写一个实体类,凡是此实体类的数据都表示需要加解密
*/
public class Encrypt {

private String value;

public Encrypt() {
}

public Encrypt(String value) {
this.value = value;
}

public String getValue() {
return value;
}

public void setValue(String value) {
this.value = value;
}
}

第四步:编写一个加解密的TypeHandler

import cn.hutool.crypto.SecureUtil;
import cn.hutool.crypto.symmetric.AES;
import org.apache.ibatis.type.BaseTypeHandler;
import org.apache.ibatis.type.JdbcType;
import org.apache.ibatis.type.MappedJdbcTypes;
import org.apache.ibatis.type.MappedTypes;
import java.nio.charset.StandardCharsets;
import java.sql.CallableStatement;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;

/**
* 加解密TypeHandler
*/
@MappedJdbcTypes(JdbcType.VARCHAR) //表示处理器处理的JDBC类型
@MappedTypes(Encrypt.class) //表示该处理器处理的java类型是什么
public class TypeHandler extends BaseTypeHandler<Encrypt> {

private static final byte[] KEYS = "12345678asdfghjkzxcv".getBytes(StandardCharsets.UTF_8);

/**
* 设置参数
*/
@Override
public void setNonNullParameter(PreparedStatement ps, int i, Encrypt parameter, JdbcType jdbcType) throws SQLException {
if (parameter == null || parameter.getValue() == null){
ps.setString(i,null);
return;
}
AES aes = SecureUtil.aes(KEYS);
String encrypt = aes.encryptHex(parameter.getValue());
ps.setString(i,encrypt);
}

/**
* 获取值
*/
@Override
public Encrypt getNullableResult(ResultSet rs, String columnName) throws SQLException {
return decrypt(rs.getString(columnName));
}

/**
* 获取值
*/
@Override
public Encrypt getNullableResult(ResultSet rs, int columnIndex) throws SQLException {
return decrypt(rs.getString(columnIndex));
}

/**
* 获取值
*/
@Override
public Encrypt getNullableResult(CallableStatement cs, int columnIndex) throws SQLException {
return decrypt(cs.getString(columnIndex));
}

private Encrypt decrypt(String value) {
if (null == value){
return null;
}
return new Encrypt(SecureUtil.aes(KEYS).decryptStr(value));
}

}

第五步:controller层对传输的数据加解密

加解密放在controller层还是其它层都可以,根据个人情况实现即可

@RestController
@RequestMapping("/pass")
public class PassUserController {

@Autowired
private PassUserServiceImpl passUserService;

/**
* 新增用户信息
*/
@PostMapping("/addUser")
public void addUser(String username,String password,Integer age){
this.passUserService.addUser(username,new Encrypt(password),age);
}

/**
* 获取用户信息
*/
@GetMapping("/getUser")
public List getUser(String password){
List<Map<String,Object>> list = this.passUserService.getUser(new Encrypt(password));
return list;
}

}

说明:service层和mapper层没有特殊说明的,跟正常实现一样

MyBatis配置进行数据加密和解密_http