在MyBatis-Plus中实现字段加密与解密

在MyBatis-Plus中实现字段加密与解密通常涉及以下步骤:

  1. 定义加密解密服务:首先,你需要定义一个服务来处理加密和解密的逻辑。

  2. 创建自定义TypeHandler:然后,你需要创建一个自定义的TypeHandler来使用这个服务来加密和解密数据。

  3. 配置MyBatis-Plus:将自定义的TypeHandler配置到MyBatis-Plus中。

  4. 使用TypeHandler:在你的实体类中使用自定义的TypeHandler。

  5. 执行写入和查询操作:使用MyBatis-Plus的通常方法来执行写入和查询操作。

以下是详细的步骤和示例:

步骤 1: 定义加密解密服务

public interface CryptoService {
    String encrypt(String input);
    String decrypt(String encrypted);
}

public class AesCryptoServiceImpl implements CryptoService {

    // 用于加密和解密的密钥
    private static final String SECRET_KEY = "your-secret-key";

    @Override
    public String encrypt(String input) {
        // 实现加密逻辑
        // ...
    }

    @Override
    public String decrypt(String encrypted) {
        // 实现解密逻辑
        // ...
    }
}

步骤 2: 创建自定义TypeHandler

import org.apache.ibatis.type.JdbcType;
import org.apache.ibatis.type.TypeHandler;

import java.sql.CallableStatement;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;

public class EncryptTypeHandler implements TypeHandler<String> {

    private final CryptoService cryptoService;

    public EncryptTypeHandler() {
        this.cryptoService = new AesCryptoServiceImpl(); // Or inject it if using Spring or similar
    }

    @Override
    public void setParameter(PreparedStatement ps, int i, String parameter, JdbcType jdbcType) throws SQLException {
        ps.setString(i, cryptoService.encrypt(parameter));
    }

    @Override
    public String getResult(ResultSet rs, String columnName) throws SQLException {
        return cryptoService.decrypt(rs.getString(columnName));
    }

    @Override
    public String getResult(ResultSet rs, int columnIndex) throws SQLException {
        return cryptoService.decrypt(rs.getString(columnIndex));
    }

    @Override
    public String getResult(CallableStatement cs, int columnIndex) throws SQLException {
        return cryptoService.decrypt(cs.getString(columnIndex));
    }
}

步骤 3: 配置MyBatis-Plus

mybatis-config.xml中注册TypeHandler:

<typeHandlers>
    <typeHandler handler="com.yourpackage.EncryptTypeHandler"/>
</typeHandlers>

或者如果你使用Java配置:

@Bean
public MybatisSqlSessionFactoryBean sqlSessionFactory() throws IOException {
    MybatisSqlSessionFactoryBean sqlSessionFactory = new MybatisSqlSessionFactoryBean();
    // ...其他配置
    sqlSessionFactory.setTypeHandlers(new TypeHandler[]{new EncryptTypeHandler()});
    return sqlSessionFactory;
}

步骤 4: 使用TypeHandler

在你的实体类中指定字段使用自定义TypeHandler:

import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableName;

@TableName(value = "user",autoResultMap = true)
public class User {
    // ...其他字段

    @TableField(typeHandler = EncryptTypeHandler.class)
    private String sensitiveData;

    // ...getters and setters
}

步骤 5: 执行写入和查询操作

写入操作:

User user = new User();
user.setSensitiveData("Some sensitive data");

userMapper.insert(user); // sensitiveData字段将自动加密

查询操作:

User user = userMapper.selectById(1);
System.out.println(user.getSensitiveData()); // sensitiveData字段将自动解密

确保在实际部署中使用安全的密钥管理策略,不要将密钥硬编码在代码中,而应该使用环境变量或密钥管理服务来存储密钥。加密和解密逻辑应该能够抵御常见的安全威胁,并且遵循最佳安全实践。

### MyBatis-Plus 敏感字段加密实现方法 #### 一、引入必要的依赖 为了在 MyBatis-Plus实现敏感字段加密,首先需要确保项目中包含了 AES 加密所需的依赖。通常情况下,在 `pom.xml` 文件中添加如下依赖即可[^2]。 ```xml <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-security</artifactId> </dependency> <!-- 如果使用的是非 Spring Boot 项目,则需单独加入 BouncyCastle 或其他支持 AES 的库 --> <dependency> <groupId>org.bouncycastle</groupId> <artifactId>bcprov-jdk15on</artifactId> <version>最新版本号</version> </dependency> ``` #### 二、创建加解密工具类 定义一个用于执行实际加解密工作的工具类,该类负责提供统一接口来完成对指定字符串类型的敏感数据进行加密解密操作。下面是一个简单的例子: ```java import javax.crypto.Cipher; import javax.crypto.KeyGenerator; import javax.crypto.SecretKey; import javax.crypto.spec.SecretKeySpec; import java.util.Base64; public class AesUtil { private static final String ALGORITHM = "AES"; public static SecretKey generateKey() throws Exception { KeyGenerator keyGen = KeyGenerator.getInstance(ALGORITHM); keyGen.init(128); // 可选参数长度为128, 192或256位 return keyGen.generateKey(); } public static byte[] encrypt(String content, SecretKey secretKey) throws Exception { Cipher cipher = Cipher.getInstance(ALGORITHM); cipher.init(Cipher.ENCRYPT_MODE, secretKey); return Base64.getEncoder().encode(cipher.doFinal(content.getBytes())); } public static String decrypt(byte[] encryptedContent, SecretKey secretKey) throws Exception { Cipher cipher = Cipher.getInstance(ALGORITHM); cipher.init(Cipher.DECRYPT_MODE, secretKey); return new String(cipher.doFinal(Base64.getDecoder().decode(encryptedContent))); } } ``` #### 三、自定义插件拦截器 通过继承 `AbstractSqlInjector` 类并重写其中的方法来自定义 SQL 注入逻辑,从而可以在每次插入/更新记录前自动调用上述工具类来进行加密处理;而在查询时则相反地先解码再返回给业务层消费。具体做法是在项目的启动类上注册此插件实例[^3]。 ```java @Component @Intercepts({ @Signature(type = Executor.class, method = "update", args = {MappedStatement.class, Object.class}), @Signature(type = Executor.class, method = "query", args = {MappedStatement.class, Object.class, RowBounds.class, ResultHandler.class}) }) public class EncryptInterceptor extends AbstractSqlInjector implements Interceptor { @Override protected void injectMap(MappedStatement ms, Class<?> mapperClass, Method method, Object... params) throws Throwable { super.injectMap(ms, mapperClass, method, params); MetaObject metaObject = SystemMetaObject.forObject(params[0]); if (metaObject.hasGetter("sensitiveData")){ // 判断是否存在名为'sensitiveData'属性 String originalValue = (String) metaObject.getValue("sensitiveData"); try{ SecretKey secretKey = AesUtil.generateKey(); // 获取秘钥对象 if ("insert".equals(method.getName()) || "updateById".equals(method.getName())) { byte[] encryptedBytes = AesUtil.encrypt(originalValue, secretKey); metaObject.setValue("sensitiveData", encryptedBytes); }else if("selectOne".equals(method.getName())){ String decryptedStr=AesUtil.decrypt((byte[])originalValue,secretKey ); metaObject.setValue("sensitiveData",decryptedStr ); } }catch(Exception e){ throw new RuntimeException(e.getMessage(),e.getCause()); } } } } ``` 以上就是关于如何利用 MyBatis-Plus 结合 Java 内置的安全机制(如 JCE)以及第三方安全组件(比如 BC 库),轻松达成数据库层面的数据保护目标的整体思路介绍[^1]。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值