zoukankan      html  css  js  c++  java
  • java实现MySQL数据加密存储---自定义mybatis处理器+mybatisplus注解

    需求 敏感字段需要加密储存到数据库 例如姓名 电话 身份证 银行卡等

    先看效果

     这里是会员表 对会员卡号 姓名  身份证号 手机号 邮箱做了加密处理

    思路

    1.自定义类型处理器  

      1.1 继承MyBatis框架 抽象类BaseTypeHandler

      1.2 重写四个方法 实现自己的加密逻辑 这里使用AES加密

    2.定义实体类

      2.1 使用MyBatis-Plus 注解@TableName 增加属性设置 autoResultMap=true

      2.2 使用MyBatis-Plus 注解@TableField 在要加密的字段设置 typeHandler=自定义的类型处理器

    说明  字段加上@TableField(typeHandler = AESEncryptHandler.class) 就可以实现你的加密逻辑了

    开始操作

    自定义类型处理器  
    public class AESEncryptHandler extends BaseTypeHandler {
    
        private final  String password = "VtW*******1w==";
    
        @Override
        public void setNonNullParameter(PreparedStatement ps, int i, Object parameter, JdbcType jdbcType) throws SQLException {
            ps.setString(i, AESUtil.encrypt((String)parameter, password));
        }
        @Override
        public String getNullableResult(ResultSet rs, String columnName) throws SQLException {
            String columnValue = rs.getString(columnName);
            return AESUtil.decrypt(columnValue, password);
        }
        @Override
        public String getNullableResult(ResultSet rs, int columnIndex) throws SQLException {
            String columnValue = rs.getString(columnIndex);
            return AESUtil.decrypt(columnValue, password);
        }
        @Override
        public String getNullableResult(CallableStatement cs, int columnIndex) throws SQLException {
            String columnValue = cs.getString(columnIndex);
            return AESUtil.decrypt(columnValue, password);
        }
    }

     AES工具类

    public class AESUtil {
    
            private static final String KEY_ALGORITHM = "AES";
        private static final String DEFAULT_CIPHER_ALGORITHM = "AES/ECB/PKCS5Padding";//默认的加密算
        
        /**
         * AES 加密操作
         *
         * @param content
         * @param password
         * @return
         */
        public static String encrypt(String content, String password) {
            try {
                Cipher cipher = Cipher.getInstance(DEFAULT_CIPHER_ALGORITHM);
    
                byte[] byteContent = content.getBytes("utf-8");
    
                cipher.init(Cipher.ENCRYPT_MODE, getSecretKey(password));// 初始化为加密模式的密码器
    
                byte[] result = cipher.doFinal(byteContent);// 加密
    
                return Base64.getEncoder().encodeToString(result);//通过Base64转码返回
            } catch (Exception ex) {
                Logger.getLogger(AESUtil.class.getName()).log(Level.SEVERE, null, ex);
            }
    
            return null;
        }
    
        /**
         * AES 解密操作
         *
         * @param content
         * @param password
         * @return
         */
        public static String decrypt(String content, String password) {
    
            try {
                Cipher cipher = Cipher.getInstance(DEFAULT_CIPHER_ALGORITHM);
    
                cipher.init(Cipher.DECRYPT_MODE, getSecretKey(password));
    
                //执行操作
                byte[] result = cipher.doFinal(Base64.getDecoder().decode(content));
    
                return new String(result, "utf-8");
            } catch (Exception ex) {
    //            log.error(ex.getMessage(),ex);
            }
    
            return null;
        }
    }

    实体类

    /**
     * 会员卡表
     * @TableName vip_card
     */
    @TableName(value ="vip_card",autoResultMap = true)
    @Data
    public class VipCard implements Serializable {
        /**
         * id
         */
        @TableId(type = IdType.AUTO)
        private Integer id;
    
        /**
         * 卡号
         */
        @TableField(typeHandler = AESEncryptHandler.class)
        private String cardNo;
    
        /**
         * 用户名
         */
        @TableField(typeHandler = AESEncryptHandler.class)
        private String name;
    
        /**
         * 性别
         */
        private Integer gender;
    
        /**
         * 年龄
         */
        private Integer age;
    
        /**
         * 邮箱
         */
        private String email;
    
        /**
         * 身份证号
         */
        @TableField(typeHandler = AESEncryptHandler.class)
        private String idNumber;
    
        /**
         * 手机号
         */
        @TableField(typeHandler = AESEncryptHandler.class)
        private String phoneNumber;
    
        /**
         * 创建时间
         */
        @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss",timezone="Asia/Shanghai")
        private Date createTime;
    
        /**
         * 更新时间
         */
        @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss",timezone="Asia/Shanghai")
        private Date updateTime;

    测试类

    @SpringBootTest
    class SecuritydemoApplicationTests {
    
        @Resource
        VipCardMapper vipCardMapper;
        
        private final static String password = "Vt**********1w==";
    
        @Test
        void add() {
            VipCard vipCard = new VipCard();
            vipCard.setCardNo("6222********99950");
            vipCard.setGender(0);
            vipCard.setName("赵三");
            vipCard.setEmail("666666@166.com");
            vipCard.setIdNumber("4101********0160");
            vipCard.setAge(19);
            vipCard.setPhoneNumber("136*****30");
            vipCard.setCreateTime(new Date());
            vipCard.setUpdateTime(new Date());
            System.out.println("新增数据>>>>>>>>>>>>>>>>>> " + vipCardMapper.insert(vipCard));
        }
    
        @Test
        void one() {
            VipCard vipCard = vipCardMapper.selectById(8);
            System.out.println("查询一条>>>>>>>>>>>>>>>>>>  " + vipCard);
        }
    
        @Test
        void list() {
            List<VipCard> vipCardList = vipCardMapper.selectList(null);
            System.out.println("查询列表>>>>>>>>>>>>>>>>>> " + vipCardList);
        }
    
        @Test
        void listByCondition() {
            QueryWrapper<VipCard> queryWrapper = new QueryWrapper<>();
    
            String Mname = AESUtil.encrypt("赵六六", password);
            queryWrapper.eq("name", Mname)
                        .eq("age", 18)
                        .eq("gender",0);
            List<VipCard> vipCardList = vipCardMapper.selectList(queryWrapper);
            System.out.println("查询列表>>>>>>>>>>>>>>>>>>  " + vipCardList);
        }
        
    
    
        @Test
        void update() {
            VipCard vipCard = new VipCard();
            vipCard.setEmail("666666@163.com");
            vipCard.setPhoneNumber("13666666666");
    
            UpdateWrapper<VipCard> updateWrapper  = new UpdateWrapper();
            String Mname = AESUtil.encrypt("赵六六", password);
            updateWrapper.eq("name", Mname);
            int update = vipCardMapper.update(vipCard, updateWrapper);
            System.out.println("更新>>>>>>>>>>>>>>>>>> " + update);
        }
    
    
        @Test
        void del(){
            Map<String,Object> map = new HashMap<>();
            String Mname = AESUtil.encrypt("赵六六", password);
            map.put("name",Mname);
            int i = vipCardMapper.deleteByMap(map);
            System.out.println("删除>>>>>>>>>>>>>>>>>> " + i);
        }
    
        @Test
        void del2(){
            String McardNo = AESUtil.encrypt("622202170289999995911", password);
            QueryWrapper<VipCard> queryWrapper = new QueryWrapper<>();
            queryWrapper.eq("card_no", McardNo);
            int i = vipCardMapper.delete(queryWrapper);
            System.out.println("删除>>>>>>>>>>>>>>>>>> " + i);
        }
        
    }

     说明  后台程序在查询数据会自动解密  查询的条件要先进行加密  不然查出来为null  因为此时入库的数据都是加密过的    不加密无法匹配数据

    最后来看下

    MyBatis内置类型处理器

    mybatis为我们实现了那么多TypeHandler

    本文就是继承了抽象类BaseTypeHandler 实现了AES加密

    古人学问无遗力,少壮工夫老始成。 纸上得来终觉浅,绝知此事要躬行。
  • 相关阅读:
    达梦数据库还原
    达梦数据库备份-Quartz定时任务备份
    达梦数据库备份-手动备份
    Hadoop集群分布式安装
    echarts实现group关系图案例
    U盘安装windows系统
    GC垃圾回收机制
    form表单提交方式实现浏览器导出Excel
    数据分析-信用卡反欺诈模型
    机器学习-SVM
  • 原文地址:https://www.cnblogs.com/wf-zhang/p/14842403.html
Copyright © 2011-2022 走看看