Java使用注解简单实现敏感数据加解密

Lewis
2022-04-22 / 0 评论 / 182 阅读 / 正在检测是否收录...
在JAVA项目开发中,我们通常需要对敏感字段进行脱敏。
import org.apache.commons.lang3.StringUtils;
import java.lang.reflect.Field;
import java.util.List;

/**
*描述:获取需要加解密的元素
*@create 2022/4/20 14:58
*/
public class BaseInfo implements Cloneable, EncryptDecryptInterface {

    @Override
    public <T> T encryptSelf() {
        toCommaint(this,EncryptFiled.class,"Encrypt");
        return (T) this;
    }

    @Override
    public <T> T decryptSelf() {
        toCommaint(this,DecryptFiled.class,"Decrypt");
        return (T) this;
    }


    @Override
    public   <T> List<T> encryptSelfList(List<T> l) {
        for (T t : l){
            toCommaint(t,EncryptFiled.class,"Encrypt");
        }
        return l;
    }

    @Override
    public <T> List<T> decryptSelfList(List<T> l) {
        for (T t : l) {
            toCommaint(t,DecryptFiled.class,"Decrypt");
        }
        return l;
    }
/**
    *描述:转换方法
    *@create 2022/4/20 16:31
    */
    public  <T> T toCommaint(T t,Class c,String type){

        Field[] declaredFields = t.getClass().getDeclaredFields();
        try {
            if (declaredFields != null && declaredFields.length > 0) {
                for (Field field : declaredFields) {
                    if (field.isAnnotationPresent(c) && field.getType().toString().endsWith("String")) {
                        field.setAccessible(true);
                        String fieldValue = (String) field.get(t);
                        if (StringUtils.isNotEmpty(fieldValue)) {

                            if(type.equals("Decrypt")){
                                fieldValue=  MySqlUtils.decrypt(fieldValue);
                            }else if(type.equals("Encrypt")){
                                fieldValue=  MySqlUtils.encrypt(fieldValue);
                            }

                            field.set(t,fieldValue);
                        }
                    }
                }
            }
        } catch (IllegalAccessException e) {
            throw new RuntimeException(e);
        }
        return t;
    }


}
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

/**
*描述:解密自定义注解
*@create 2022/4/20 14:11
*/
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
public @interface DecryptFiled {
    String value() default "";
}
import java.util.List;

/**
*描述:Base类实现该接口中的自加密自解密方法
*@create 2022/4/20 14:10
*/
public interface EncryptDecryptInterface {
    public <T> T encryptSelf();
    public <T> T decryptSelf();

    public <T> List<T>  encryptSelfList(List<T> c);
    public <T> List<T>  decryptSelfList(List<T> c);

}
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;


/**
*描述:加密自定义注解
*@create 2022/4/20 14:08
*/
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
public @interface EncryptFiled {
    String value() default "";
}
import org.springframework.stereotype.Component;
import javax.crypto.Cipher;
import javax.crypto.spec.SecretKeySpec;

/**
*描述:
*@create 2022/4/20 14:49
*/
@Component
public class MySqlUtils {
    private static final String KEY_AES = "AES";//加密格式
    private static final String key="dongguan_key$123";//秘钥 长度必须是 16 bytes


    /**
    *描述:数据加密
    *@create 2022/4/20 14:44
    */
    public static String encrypt(String src)  {
      try {
          byte[] raw = key.getBytes();
          SecretKeySpec skeySpec = new SecretKeySpec(raw, KEY_AES);
          Cipher cipher = Cipher.getInstance(KEY_AES);
          cipher.init(Cipher.ENCRYPT_MODE, skeySpec);
          byte[] encrypted = cipher.doFinal(src.getBytes());
          src= byte2hex(encrypted);
      }catch (Exception e){
          System.out.println("加密数据出错="+e);
      }
      return src;

    }


    /**
    *描述:数据解密
    *@create 2022/4/20 14:45
    */
    public static String decrypt(String src) {
        try {
            byte[] raw = key.getBytes();
            SecretKeySpec skeySpec = new SecretKeySpec(raw, KEY_AES);
            Cipher cipher = Cipher.getInstance(KEY_AES);
            cipher.init(Cipher.DECRYPT_MODE, skeySpec);
            byte[] encrypted1 = hex2byte(src);
            byte[] original = cipher.doFinal(encrypted1);
            src = new String(original);
        }catch (Exception e){
            System.out.println("加密数据出错="+e);
        }
        return src;
    }


    public static byte[] hex2byte(String strhex) {
        if (strhex == null) {
            return null;
        }
        int l = strhex.length();
        if (l % 2 == 1) {
            return null;
        }
        byte[] b = new byte[l / 2];
        for (int i = 0; i != l / 2; i++) {
            b[i] = (byte) Integer.parseInt(strhex.substring(i * 2, i * 2 + 2),
                    16);
        }
        return b;
    }


    public static String byte2hex(byte[] b) {
        StringBuilder hs = new StringBuilder();
        String stmp = "";
        for (int n = 0; n < b.length; n++) {
            stmp = (Integer.toHexString(b[n] & 0XFF));
            if (stmp.length() == 1) {
                hs.append("0").append(stmp);
            } else {
                hs.append(stmp);
            }
        }
        return hs.toString().toUpperCase();
    }


    public static void main(String[] args) throws Exception {
        String content = "testContext";
        System.out.println("原内容 = " + content);
        String encrypt = MySqlUtils.encrypt(content);
        System.out.println("加密后 = " + encrypt);
        String decrypt = MySqlUtils.decrypt(encrypt);
        System.out.println("解密后 = " + decrypt);
    }


}
import com.alibaba.fastjson.JSON;

import java.util.ArrayList;
import java.util.List;

/**
*描述:测试
*@create 2022/4/20 14:50
*/
public class Test {

    public static void main(String[] args) {
        TestPo sd = new TestPo();//要进行加密解密的实体类
        sd.setIdcard("6029131988005021537");//注入身份证号
        sd.setName("小小");

        TestPo sd1 = new TestPo();//要进行加密解密的实体类
        sd1.setIdcard("6029131988005021538");//注入身份证号
        sd1.setPhone("15919314668");

        TestPo sd2 = new TestPo();//要进行加密解密的实体类
        sd2.setIdcard("6029131988005021539");//注入身份证号
        sd2.setPhone("15919314669");


        List<TestPo> lists=new ArrayList<>();
        lists.add(sd);
        lists.add(sd1);
        lists.add(sd2);

        List<TestPo> listjm=sd.encryptSelfList(lists);
        System.out.println("执行自加密后输出:"+JSON.toJSONString(listjm) );//执行自加密后输出


        List<TestPo> listem=sd.decryptSelfList(listjm);
        System.out.println("执行自解密后输出:"+JSON.toJSONString(listem) );//执行自解密后输出


        TestPo od1=sd.encryptSelf();
        System.out.println("加密"+JSON.toJSONString(od1) );//执行自加密后输出

        TestPo od2=od1.decryptSelf();
        System.out.println("解密"+JSON.toJSONString(od2));//执行自解密后输出
    }
}
/**
*描述:po
*@create 2022/4/20 16:21
*/
public class TestPo extends BaseInfo {

    private int id;

    @DecryptFiled
    @EncryptFiled
    private String idcard;

    @DecryptFiled
    @EncryptFiled
    private String phone;

    private String name;

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public String getIdcard() {
        return idcard;
    }

    public void setIdcard(String idcard) {
        this.idcard = idcard;
    }

    public String getPhone() {
        return phone;
    }

    public void setPhone(String phone) {
        this.phone = phone;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }
}
0

评论 (0)

取消