Mybatis 의 TypeHandler 복호화 데이터 구현

배경
저희 데이터 베이스 에 일부 사용자 의 민감 한 정 보 를 저장 할 때 가 있 습 니 다.예 를 들 어 핸드폰 번호,은행 카드 등 정 보 는 이런 정 보 를 명문 으로 저장 하면 안전 하지 않 습 니 다.만약 해커 가 데이터베이스 에 해 킹 을 하거나 이 직 자가 데 이 터 를 내 보 냈 다 면 이런 민감 한 데이터 가 유출 될 수 있다.그래서 우 리 는 이 문 제 를 해결 할 방법 을 찾 아야 한다.
해결 방안
Google 시스템 에 서 는 데이터베이스 영구 층 으로 Mybatis 를 사 용 했 기 때문에 Mybatis 의 TypeHandler 나 Plugin 을 사용 하여 해결 하기 로 결 정 했 습 니 다.
TypeHandler:어떤 열 에 typeHandler 를 수 동 으로 지정 하여 그 typeHandler 를 사용 하거나@MappedJdbcTypes 와@MappedTypes 주석 에 따라 스스로 추정 해 야 합 니 다.

<result column="phone" property="phone" typeHandler="com.huan.study.mybatis.typehandler.EncryptTypeHandler"/>
Plugin:시스템 의 select,insert,update,delete 등 문 구 를 차단 할 수 있 고 sql 실행 전의 매개 변수 와 실행 후의 데 이 터 를 얻 을 수 있 습 니 다.
고려 를 거 쳐 TypeHandler 를 사용 하여 데 이 터 를 복호화 하기 로 결정 했다.
수요
저 희 는 고객 표 customer 가 있 습 니 다.그 안에 고객 의 핸드폰 번호(phone)와 고객 주소(address)등 필드 가 있 습 니 다.그 중에서 고객 의 핸드폰 번호(phone)는 데이터베이스 에 암호 화 되 어 저장 해 야 합 니 다.
1.고객 정 보 를 추가 할 때 자동 으로 고객 핸드폰 번 호 를 암호 화하 여 데이터 에 저장 합 니 다.
2.고객 정 보 를 조회 할 때 고객 의 핸드폰 번 호 를 자동 으로 복호화 합 니 다.
4.사고 방향 실현
1.실체 클래스 를 작성 합 니 다.이 실체 클래스 의 데 이 터 는 복호화 가 필요 하 다 는 것 을 표시 합 니 다.

public class Encrypt {
    private String value;

    public Encrypt() {
    }

    public Encrypt(String value) {
        this.value = value;
    }

    public String getValue() {
        return value;
    }

    public void setValue(String value) {
        this.value = value;
    }
}

2.복호화 된 TypeHandler 를 작성 합 니 다.
  • 파 라 메 터 를 설정 할 때 데 이 터 를 암호 화 합 니 다.
  • 데이터베이스 에서 기록 을 가 져 올 때 데 이 터 를 복호화 합 니 다.
  • 
    package com.huan.study.mybatis.typehandler;
    
    import cn.hutool.crypto.SecureUtil;
    import cn.hutool.crypto.symmetric.AES;
    import org.apache.ibatis.type.BaseTypeHandler;
    import org.apache.ibatis.type.JdbcType;
    import org.apache.ibatis.type.MappedJdbcTypes;
    import org.apache.ibatis.type.MappedTypes;
    
    import java.nio.charset.StandardCharsets;
    import java.sql.CallableStatement;
    import java.sql.PreparedStatement;
    import java.sql.ResultSet;
    import java.sql.SQLException;
    
    /**
     *    TypeHandler
     *
     * @author huan.fu 2021/5/18 -   9:20
     */
    @MappedJdbcTypes(JdbcType.VARCHAR)
    @MappedTypes(Encrypt.class)
    public class EncryptTypeHandler extends BaseTypeHandler<Encrypt> {
    
        private static final byte[] KEYS = "12345678abcdefgh".getBytes(StandardCharsets.UTF_8);
    
        /**
         *     
         */
        @Override
        public void setNonNullParameter(PreparedStatement ps, int i, Encrypt parameter, JdbcType jdbcType) throws SQLException {
            if (parameter == null || parameter.getValue() == null) {
                ps.setString(i, null);
                return;
            }
            AES aes = SecureUtil.aes(KEYS);
            String encrypt = aes.encryptHex(parameter.getValue());
            ps.setString(i, encrypt);
        }
    
        /**
         *    
         */
        @Override
        public Encrypt getNullableResult(ResultSet rs, String columnName) throws SQLException {
            return decrypt(rs.getString(columnName));
        }
    
        /**
         *    
         */
        @Override
        public Encrypt getNullableResult(ResultSet rs, int columnIndex) throws SQLException {
            return decrypt(rs.getString(columnIndex));
        }
    
        /**
         *    
         */
        @Override
        public Encrypt getNullableResult(CallableStatement cs, int columnIndex) throws SQLException {
            return decrypt(cs.getString(columnIndex));
        }
    
        public Encrypt decrypt(String value) {
            if (null == value) {
                return null;
            }
            return new Encrypt(SecureUtil.aes(KEYS).decryptStr(value));
        }
    }
    
    
    주의 하 다.⚠️:
  • @MappedTypes:이 프로세서 가 처리 하 는 자바 형식 이 무엇 인지 표시 합 니 다.
  • @MappedJdbcTypes:프로세서 가 처리 하 는 Jdbc 형식 을 표시 합 니 다.
  • 3.sql 구문 쓰기
    
    <?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
    <mapper namespace="com.huan.study.mybatis.mappers.CustomerMapper">
    
        <resultMap id="BaseResultMapper" type="com.huan.study.mybatis.entity.Customer">
            <id column="id" property="id"/>
            <result column="phone" property="phone"/>
            <result column="address" property="address"/>
        </resultMap>
    
        <insert id="addCustomer">
            insert into customer(phone,address) values (#{phone},#{address})
        </insert>
    
        <select id="findCustomer" resultMap="BaseResultMapper">
            select * from customer where phone = #{phone}
        </select>
    
    </mapper>
    
    
    SQL 에는 특별한 문법 이 없습니다.
    4.설정 파일 에서 Typehandler 의 패키지 경 로 를 지정 합 니 다.
    
    mybatis.type-handlers-package=com.huan.study.mybatis.typehandler
    
    5.배경 코드 작성
  • 추가 방법 을 제공 합 니 다
  • 핸드폰 번호 에 따라 조회 하 는 방법 을 제공 합 니 다
  • 배경 코드 가 간단 합 니 다.직접 보기https://gitee.com/huan1993/spring-cloud-parent/tree/master/mybatis/mybatis-typehandler-encrypt
    mapper 층 의 캡 처 를 붙 입 니 다.

    mapper 층 의 쓰기
    6.테스트 결과

    데이터베이스 필드 복호화 결과
    테스트 결과 에서 알 수 있 듯 이 데 이 터 를 추가 할 때 암호 화 되 어야 할 데이터(phone)는 데이터베이스 에서 암호 화 되 었 고 조회 할 때 암호 화 된 데 이 터 는 자동 으로 복호화 되 었 다.
    실현 코드
    배경 코드:https://gitee.com/huan1993/spring-cloud-parent/tree/master/mybatis/mybatis-typehandler-encrypt
    참고 문서
    1、 https://mybatis.org/mybatis-3/zh/configuration.html#typeHandlers
    2、 https://github.com/mybatis/spring-boot-starter
    Mybatis 의 TypeHandler 에 복호화 데 이 터 를 추가 하여 이 루어 진 이 글 은 여기까지 소개 되 었 습 니 다.더 많은 관련 Mybatis TypeHandler 에 복호화 내용 을 추가 하려 면 예전 의 글 을 검색 하거나 아래 의 관련 글 을 계속 찾 아 보 세 요.앞으로 많은 응원 부 탁 드 리 겠 습 니 다!

    좋은 웹페이지 즐겨찾기