1. 需求背景
项目采用MyBatis-Plus作为ORM工具,近期需要对手机号,账户等敏感信息进行加密存储。
考虑到MyBatis提供了BaseTypeHandler,可以继承此对字段进行自定义操作,于是创建以下解决方案
2. 加解密Handler
因为加密的字段,在部分场景下还需要提取出来执行业务操作,因此此处选用AES对称加密解决方案。
此处,AesEncryptHandler
继承BaseTypeHandler
,对数据库中的varchar字段进行加解密操作,具体代码如下所示:
@Slf4j
@MappedTypes({String.class})
@MappedJdbcTypes(JdbcType.VARCHAR)
public class AesEncryptHandler extends BaseTypeHandler<String> {
private static final byte[] KEY = "zluzuagohu1b9kyayluzuagohu913kyz".getBytes(StandardCharsets.UTF_8);
private static final byte[] IV = "arbqu12x9ixx0fej".getBytes(StandardCharsets.UTF_8);
@Override
public void setNonNullParameter(PreparedStatement ps, int i, String parameter, JdbcType jdbcType) throws SQLException {
AES aes = new AES("CBC", "PKCS5Padding", KEY, IV);
ps.setString(i, aes.encryptBase64(parameter, StandardCharsets.UTF_8));
}
@Override
public String getNullableResult(ResultSet rs, String columnName) throws SQLException {
var res = rs.getString(columnName);
if (CharSequenceUtil.isEmpty(res)) {
return res;
}
AES aes = new AES("CBC", "PKCS5Padding", KEY, IV);
return aes.decryptStr(res, StandardCharsets.UTF_8);
}
@Override
public String getNullableResult(ResultSet rs, int columnIndex) throws SQLException {
var res = rs.getString(columnIndex);
if (CharSequenceUtil.isEmpty(res)) {
return res;
}
AES aes = new AES("CBC", "PKCS5Padding", KEY, IV);
return aes.decryptStr(res, StandardCharsets.UTF_8);
}
@Override
public String getNullableResult(CallableStatement cs, int columnIndex) throws SQLException {
var res = cs.getString(columnIndex);
if (CharSequenceUtil.isEmpty(res)) {
return res;
}
AES aes = new AES("CBC", "PKCS5Padding", KEY, IV);
return aes.decryptStr(res, StandardCharsets.UTF_8);
}
}
3. 加密字段配置
@Data
@NoArgsConstructor
@EqualsAndHashCode(callSuper = true)
@TableName(autoResultMap = true)
public class SysUser extends BaseEntity {
@TableField("`name`")
private String name;
@TableField(typeHandler = AesEncryptHandler.class)
private String phone;
}
参考上文代码示例,需要在实体类上添加@TableName(autoResultMap = true)
,以及在需要加解密的字段上添加@TableField(typeHandler = AesEncryptHandler.class)
注解。
4. 项目配置文件
项目配置文件中,需要添加type-handlers-package
配置项,以便MyBatis-Plus注入加解密Handler。
具体如下所示:
mybatis-plus:
global-config:
db-config:
logic-delete-value: 1
logic-not-delete-value: 0
logic-delete-field: deleted
id-type: auto
configuration:
map-underscore-to-camel-case: true
mapper-locations: classpath*:mapper/*.xml
type-aliases-package: com.doudou.cm.entity
type-handlers-package: com.doudou.cm.handler