SpringBoot结合MyBatis实现数据库字段加密

 更新时间:2025年12月24日 09:35:06   作者:子墨老师  
这篇文章主要为大家详细介绍了SpringBoot如何结合MyBatis实现数据库字段加密功能,文中的示例代码讲解详细,感兴趣的小伙伴可以了解下

今天分享一篇基于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数据库字段加密内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • 关于使用MyBatis简化JDBC开发和解决SQL语句警告的问题

    关于使用MyBatis简化JDBC开发和解决SQL语句警告的问题

    这篇文章主要介绍了关于使用MyBatis简化JDBC开发和解决SQL语句警告的问题,如果idea和数据库没有建立链接,idea不识别表的信息,就会出现SQL语句的警告,需要的朋友可以参考下
    2023-05-05
  • JustAuth整合第三方登录组件样例

    JustAuth整合第三方登录组件样例

    这篇文章主要为大家介绍了JustAuth整合第三方登录组件样例详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2023-07-07
  • Spring Bean获取方式的实例化方式详解

    Spring Bean获取方式的实例化方式详解

    工作中需要对一个原本加载属性文件的工具类修改成对数据库的操作当然,ado层已经写好,但是需要从Spring中获取bean,然而,工具类并没有交给Spring来管理,所以需要通过方法获取所需要的bean。于是整理了Spring获取bean的几种方法
    2023-03-03
  • 三道MySQL新手入门面试题,通往自由的道路

    三道MySQL新手入门面试题,通往自由的道路

    这篇文章主要为大家分享了最有价值的3道MySQL面试题,,感兴趣的小伙伴们可以参考一下
    2021-07-07
  • 解决mybatis plus报错Invalid bound statement (not found):问题

    解决mybatis plus报错Invalid bound statement 

    在使用MyBatis时遇到InvalidBoundStatement异常,常因多个MapperScan配置冲突或者包扫描路径设置错误,解决方法包括保留一个MapperScan声明、检查jar包冲突、确保命名空间和扫描路径正确,使用@TableId注解指定主键
    2024-11-11
  • elasticsearch构造Client实现java客户端调用接口示例分析

    elasticsearch构造Client实现java客户端调用接口示例分析

    这篇文章主要为大家介绍了elasticsearch构造Client实现java客户端调用接口示例分析,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2022-04-04
  • SpringBoot自定义消息转换器的实现与应用

    SpringBoot自定义消息转换器的实现与应用

    Spring Boot 默认提供了多种消息转换器,如 Jackson 用于 JSON 格式转换、JAXB 用于 XML 格式转换等,然而,实际开发中往往需要根据业务需求进行自定义的消息转换器,文将详细介绍如何在 Spring Boot 中实现自定义消息转换器,探讨其工作原理、配置方式以及实际应用场景
    2025-01-01
  • java集合与数组的相同点和不同点

    java集合与数组的相同点和不同点

    今天小编就为大家分享一篇关于java集合与数组的相同点和不同点,小编觉得内容挺不错的,现在分享给大家,具有很好的参考价值,需要的朋友一起跟随小编来看看吧
    2019-04-04
  • idea mabatisX插件生成mapper.xml文件全过程

    idea mabatisX插件生成mapper.xml文件全过程

    文章介绍了如何在IntelliJ IDEA中使用MybatisX插件自动生成MyBatis的Mapper和XML文件,步骤包括安装插件、选择数据库表并右键选择MybatisX-Generator进行配置和生成
    2026-03-03
  • SpringBoot中使用@scheduled定时执行任务的坑

    SpringBoot中使用@scheduled定时执行任务的坑

    本文主要介绍了SpringBoot中使用@scheduled定时执行任务的坑,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2022-05-05

最新评论