背景
为响应国家 《数据安全法》的要求,我司数据安全部门要求各个业务部门将现存所有 mysql 表中敏感字段加密存储。而我所负责的系统模块有 10 几张表分布在 3 ~ 4 个微服务中,因此我想设计一个通用的改动最少方法对这些表字段加密。
1.0 版本设计
因我司大部分项目使用的是 mybatis 或者 mybatis-plus ORM 框架,所以 1.0 版本的设计是使用 mybatis 拦截器 interceptor 做数据的加密和解密。
遇到的问题
mybatis generator 可以生成多种方式的 mapper
xxxExample 格式的查询语句
dynamic sql 格式的查询
解决方案
1.1 版本设计
mybatis 拦截器 + jsqlparser
2.0 版本设计
因 1.0 版本和 1.1 版本设计的各种问题,需要一种通用性更强的设计,经过各种百度先后确定使用 apache shardingsphere-jdbc encrypt 模块来做加解密。
遇到的问题
mysql schema meta 无法获取
ShardingSphereResultSet
EncryptMergedResult:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41
| public final class EncryptMergedResult implements MergedResult {
private final EncryptAlgorithmMetaData metaData;
private final MergedResult mergedResult;
@Override public boolean next() throws SQLException { return mergedResult.next(); }
@SuppressWarnings({"rawtypes", "unchecked"}) @Override public Object getValue(final int columnIndex, final Class<?> type) throws SQLException { Optional<EncryptContext> encryptContext = metaData.findEncryptContext(columnIndex); if (!encryptContext.isPresent() || !metaData.isQueryWithCipherColumn(encryptContext.get().getTableName(), encryptContext.get().getColumnName())) { return mergedResult.getValue(columnIndex, type); } Optional<EncryptAlgorithm> encryptAlgorithm = metaData.findEncryptor(encryptContext.get().getTableName(), encryptContext.get().getColumnName()); if (!encryptAlgorithm.isPresent()) { return mergedResult.getValue(columnIndex, type); } Object cipherValue = mergedResult.getValue(columnIndex, Object.class); return null == cipherValue ? null : encryptAlgorithm.get().decrypt(cipherValue, encryptContext.get()); }
@Override public Object getCalendarValue(final int columnIndex, final Class<?> type, final Calendar calendar) throws SQLException { return mergedResult.getCalendarValue(columnIndex, type, calendar); }
@Override public InputStream getInputStream(final int columnIndex, final String type) throws SQLException { return mergedResult.getInputStream(columnIndex, type); }
@Override public boolean wasNull() throws SQLException { return mergedResult.wasNull(); } }
|
解决方案
拉取 shardingsphere 源码 修改/编译/打包/发私服
总结