使用Java Agent 插桩技术:实现 DB中敏感字段自动加解密

在上篇文章中由于字数限制,没有将本文内容加进去,所以这里单独写一篇关于Java Agnet实际应用的文章。

如果你看完了上篇文章:关于Java Agent的使用、工作原理、及hotspot源码 解析,那么此篇的应用文章就相当轻松了 当然你需要使用过 mybatis plus 这个框架(因为我们本文是对这个框架的代码进行插桩) 不过我想干Java的这个(mybatis plus)应该是基本功,对这个框架就不多介绍了。

1、我们的目的:(写时加密,读时解密)

因为我这里使用baomidou(mybatis plus)开发的,所以直接找到这个方法(注意我可不是凭想象来的而是经过了对增删改查这几个方法的debug 最终发现baomidou的mybatis plus最终都会走com.baomidou.mybatisplus.core.override.MybatisMapperMethod类的execute方法,如下:) image.png 所以说需要插桩的地方我们就找到了。接下来开干!

2、编写Java Agent

2.1、编写premain方法并实现ClassFileTransformer的transform类,以便类加载时回调到transform 从而对指定的类中的方法进行增强即 插桩!

```java

package com.xzll.agent.config;

import com.xzll.agent.config.advice.MysqlFieldEncryptAndDecryptAdvice; import javassist.*;

import java.lang.instrument.ClassFileTransformer; import java.lang.instrument.IllegalClassFormatException; import java.lang.instrument.Instrumentation; import java.security.ProtectionDomain;

/** * @Author: hzz * @Date: 2023/3/3 09:15:21 * @Description: MYSQL加解密 agent */ public class MysqlFieldCryptByExecuteBodyAgent {

/** * 实现了带Instrumentation参数的premain()方法。 */ public static void premain(String args, Instrumentation inst) throws Exception { //调用addTransformer()方法对启动时所有的类(应用层)进行拦截 inst.addTransformer(new MysqlReadWriteTransformer(), true); }

static class MysqlReadWriteTransformer implements ClassFileTransformer { /* * 如果事先知道哪些类需要修改,最简单的修改类方式如下: *

* 1、通过调用ClassPool.get()方法获取一个CtClass对象 * 2、修改它 * 3、调用CtClass对象的writeFile()或toBytecode()方法获取修改后的类文件 *

/ @Override public byte[] transform(ClassLoader loader, String className, Class> classBeingRedefined, ProtectionDomain protectionDomain, byte[] classfileBuffer) throws IllegalClassFormatException { //拦截指定要插桩 & 增强的类 if ("com/baomidou/mybatisplus/core/override/MybatisMapperMethod".equals(className)) { CtClass clazz = null; System.out.println("对MybatisMapperMethod执行插桩实现读解密,写加密。"); try { // 从ClassPool获得CtClass对象 (ClassPool对象是CtClass对象的容器,CtClass对象是类文件的抽象表示) final ClassPool classPool = ClassPool.getDefault(); //这一步必不可少 和类加载器有关系,且maven中要配置 addClasspath=true //不加的话插桩时找不到MysqlFieldEncryptAndDecryptAdvice这个类 classPool.insertClassPath(new ClassClassPath(MysqlFieldEncryptAndDecryptAdvice.class)); clazz = classPool.get("com.baomidou.mybatisplus.core.override.MybatisMapperMethod"); CtMethod getTime = clazz.getDeclaredMethod("execute"); String body = "{\n" + "return com.xzll.agent.config.advice.MysqlFieldEncryptAndDecryptAdvice.executeAgent($0,$1,$2);\n" + "}\n"; getTime.setBody(body); //通过CtClass的toBytecode(); 方法来获取 被修改后的字节码 return clazz.toBytecode(); } catch (Exception ex) { ex.printStackTr
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值