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加密

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM