在实际开发中遇到这样一个问题分享给大家
针对不同数据库的敏感数据进行加密解密
在这里主要针对程序生成环境存在多个数据库,如果是单一库版本可以使用
数据库自定加解密函数。(由于数据库不同存在数据库更换以后,程序异常问题,所以在这里我用了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 " />
感兴趣的小伙伴去试试吧