针对不同数据库的敏感数据进行加密解密

本文介绍在项目开发中如何使用TypeHandler解决不同数据库敏感数据的加密和解密问题,以AES加密为例,包括AESEncryptHandler和AESDecoder类的实现及在MyBatis中的应用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

在实际开发中遇到这样一个问题分享给大家
针对不同数据库的敏感数据进行加密解密
在这里主要针对程序生成环境存在多个数据库,如果是单一库版本可以使用
数据库自定加解密函数。(由于数据库不同存在数据库更换以后,程序异常问题,所以在这里我用了TypeHandler)。
首先给大家介绍一下TypeHandler
TypeHandler主要是用于mybatis对于自定义类型处理
要实现对敏感数据加密我这里用到了自定义TypeHandler
要实现typeHandler就要实现接口 typeHandler 或者集成接口BaseTypeHandler.

这里用到的是BaseTypeHandler
首先加解密类(ASE,如果需要支持模糊查询可以采用Base64之类的转码加密)

package com.efiles.common.aes;


import javax.crypto.Cipher;
import javax.crypto.KeyGenerator;
import javax.crypto.NoSuchPaddingException;
import javax.crypto.SecretKey;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.security.SecureRandom;

public class AESDecoder {
    public static String decrypt4Aes2Str(String contentbase64 ,String aesKey) {

        String Result = null;

        try {

            byte[] dst = decrypt4Aes(contentbase64 ,aesKey);

            if (null != dst) {

                Result = new String(dst, "UTF-8");

            }

        } catch (Exception e3) {

        }

        return Result;

    }

    public static byte[] decrypt4Aes(String contentbase64 ,String aesKey) {

        try {

            byte[] src = base64decode(contentbase64);


            return decryptMode(src ,aesKey);

        } catch (Exception e3) {

        }

        return null;

    }

    public static byte[] decryptMode(byte[] src ,String aesKey) {

        try {

            Cipher cip = Cipher.getInstance("AES");

            cip.init(Cipher.DECRYPT_MODE, getSecretKey(aesKey));

            return cip.doFinal(src);

        } catch (Exception e3) {

        }

        return null;

    }


    public static byte[] base64decode(String s) {

        if (s == null)
            return null;

        sun.misc.BASE64Decoder decoder = new sun.misc.BASE64Decoder();

        try {

            byte[] b = decoder.decodeBuffer(s);

            return b;

        } catch (Exception e) {

            return null;

        }

    }

    public static SecretKey getSecretKey(String aesKey) throws NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeyException {

        byte[] keybyte = getKeyByStr(aesKey);// toReplace

        SecureRandom secureRandom = SecureRandom.getInstance("SHA1PRNG");

        secureRandom.setSeed(keybyte);

        KeyGenerator keygen = KeyGenerator.getInstance("AES");

        keygen.init(secureRandom);

        return keygen.generateKey();

    }

    public static byte[] getKeyByStr(String str) {

        byte[] bRet = new byte[str.length() / 2];

        for (int i = 0; i < str.length() / 2; i++) {

            Integer itg = new Integer(16 * getChrInt(str.charAt(2 * i)) + getChrInt(str.charAt(2 * i + 1)));

            bRet[i] = itg.byteValue();

        }

        return bRet;

    }

    public static int getChrInt(char chr) {

        int iRet = 0;

        if (chr == "0".charAt(0))
            iRet = 0;

        if (chr == "1".charAt(0))
            iRet = 1;

        if (chr == "2".charAt(0))
            iRet = 2;

        if (chr == "3".charAt(0))
            iRet = 3;

        if (chr == "4".charAt(0))
            iRet = 4;

        if (chr == "5".charAt(0))
            iRet = 5;

        if (chr == "6".charAt(0))
            iRet = 6;

        if (chr == "7".charAt(0))
            iRet = 7;

        if (chr == "8".charAt(0))
            iRet = 8;

        if (chr == "9".charAt(0))
            iRet = 9;

        if (chr == "A".charAt(0))
            iRet = 10;

        if (chr == "B".charAt(0))
            iRet = 11;

        if (chr == "C".charAt(0))
            iRet = 12;

        if (chr == "D".charAt(0))
            iRet = 13;

        if (chr == "E".charAt(0))
            iRet = 14;

        if (chr == "F".charAt(0))
            iRet = 15;

        return iRet;

    }

}

/**
 * @author mcx
 * @apiNote AES加密方式 不支持模糊查询
 * @date 2022/4/24
 */
@MappedJdbcTypes(JdbcType.VARCHAR)
@MappedTypes(String.class)
public class AESEncryptHandler extends BaseTypeHandler <String>{
    private final String key = "CPnb66hrzjgzKfGoTbXgndWG";
	//对插入数据进行加密
    @Override
    public void setNonNullParameter(PreparedStatement ps, int i, String parameter, JdbcType jdbcType) throws SQLException {
        ps.setString(i, AESEncoder.encrypt4Aes((String)parameter, key));
    }


//对查询数据进行解密
    @Override
    public String getNullableResult(ResultSet rs, String columnName) throws SQLException {
        String columnValue = rs.getString(columnName);
        return AESDecoder.decrypt4Aes2Str(columnValue, key);
    }
    //对查询数据进行解密
    @Override
    public String getNullableResult(ResultSet rs, int columnIndex) throws SQLException {
        String columnValue = rs.getString(columnIndex);
        return AESDecoder.decrypt4Aes2Str(columnValue, key);
    }
    //对查询数据进行解密
    @Override
    public String getNullableResult(CallableStatement cs, int columnIndex)
            throws SQLException {
        String columnValue = cs.getString(columnIndex);
        return AESDecoder.decrypt4Aes2Str(columnValue, key);

    }
}

如何使用

加密使用
#{fileTitle,typeHandler =com.common.typeHandler.AESEncryptHandler }
解密使用

<result column="Title" property="title" typeHandler="com.common.typeHandler.AESEncryptHandler " />

感兴趣的小伙伴去试试吧

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值