今天分享一篇基于springboot+mybatis来实现数据库字段加密的操作,喜欢的朋友可以借鉴
大致的实现流程
业务层-->系统拦截器-->数据库-->系统拦截器-->返回结果
加密注解设计
把需要加密的字段通过我们自定义的加密注解进行标识,所以我们需要先自定义一段加密注解的代码
@target(elementtype.field)
@retention(retentionpolicy.runtime)
public @interface encrypt {
}实体类
在实体类上使用注解标记需要加密字段
@data
public class user {
private long id;
private string username;
@encrypt
private string password;
@encrypt
private string email;
@encrypt
private string phone;
}加密工具类
基于aes加密算法实现对字段名的加密,大家可以选择其他的加密算法
public class encryptionutil {
privatestaticfinal string algorithm = "aes";
privatestaticfinal string transformation = "aes/ecb/pkcs5padding";
// aes加密
public static string encrypt(string plaintext, string key) {
try {
secretkeyspec secretkey = new secretkeyspec(key.getbytes(standardcharsets.utf_8), algorithm);
cipher cipher = cipher.getinstance(transformation);
cipher.init(cipher.encrypt_mode, secretkey);
byte[] encryptedbytes = cipher.dofinal(plaintext.getbytes(standardcharsets.utf_8));
return base64.getencoder().encodetostring(encryptedbytes);
} catch (exception e) {
thrownew runtimeexception("加密失败", e);
}
}
// aes解密
public static string decrypt(string ciphertext, string key) {
try {
secretkeyspec secretkey = new secretkeyspec(key.getbytes(standardcharsets.utf_8), algorithm);
cipher cipher = cipher.getinstance(transformation);
cipher.init(cipher.decrypt_mode, secretkey);
byte[] decryptedbytes = cipher.dofinal(base64.getdecoder().decode(ciphertext));
returnnew string(decryptedbytes, standardcharsets.utf_8);
} catch (exception e) {
thrownew runtimeexception("解密失败", e);
}
}
}系统拦截器设计
通过拦截实现自动加密和自动解密
// 加密拦截器
@intercepts({
@signature(type = executor.class, method = "update", args = {mappedstatement.class, object.class})
})
@component
public class fieldencryptioninterceptor implements interceptor {
@value("${encryption.key:mysecretkey12345}")
private string encryptionkey;
@override
public object intercept(invocation invocation) throws throwable {
object[] args = invocation.getargs();
mappedstatement mappedstatement = (mappedstatement) args[0];
object parameter = args[1];
// 获取sql命令类型
string sqlcommandtype = mappedstatement.getsqlcommandtype().tostring();
// 对insert和update操作进行加密处理
if ("insert".equals(sqlcommandtype) || "update".equals(sqlcommandtype)) {
encryptfields(parameter);
}
return invocation.proceed();
}
// 解密拦截器
@intercepts({
@signature(type = resultsethandler.class, method = "handleresultsets", args = {statement.class})
})
@component
public class fielddecryptioninterceptor implements interceptor {
@value("${encryption.key:mysecretkey12345}")
private string encryptionkey;
@override
public object intercept(invocation invocation) throws throwable {
// 执行原始方法
object result = invocation.proceed();
// 对查询结果进行解密处理
if (result instanceof list) {
list<?> list = (list<?>) result;
for (object item : list) {
decryptfields(item);
}
} else {
decryptfields(result);
}
return result;
}
}
}测试场景
- 用户信息保护:在用户注册时,自动加密用户的密码、邮箱、手机号等敏感信息,即使数据库泄露也不会造成用户隐私泄露
- 金融数据保护:对用户的银行卡号、交易记录等金融数据进行加密存储,满足金融行业的合规要求
- 医疗医保数据保护:对患者的病历、诊断结果等医疗隐私数据进行加密,保护患者隐私
- 企业数据保护:对企业内部的商业机密、客户资料等重要数据进行加密保护
注意事项
- 虽然字段级加密功能强大,但在生产环境中使用时必须注意安全性:
- 密钥管理:不要在代码中硬编码密钥,应使用专业的密钥管理系统
- 算法选择:使用经过验证的加密算法,如aes-256
- 性能优化:合理选择需要加密的字段,避免对所有字段都进行加密
- 审计日志:记录所有加密解密操作,便于安全审计
- 定期轮换:定期更换加密密钥,降低密钥泄露风险
到此这篇关于springboot结合mybatis实现数据库字段加密的文章就介绍到这了,更多相关springboot mybatis数据库字段加密内容请搜索代码网以前的文章或继续浏览下面的相关文章希望大家以后多多支持代码网!
发表评论