山东网站建设最便宜,哪个装修公司比较好,软件工程开发流程,做网站的公司有多少家文章目录什么是脱敏脱敏后带来什么问题解决方案一解决方案二具体实施方案一方案二存量数据处理什么是脱敏
如果你有申请过一些软件资质#xff0c;应该会被要求敏感数据进行加密#xff0c;比如密码不能明文#xff0c;用户的手机号#xff0c;身份证信息#xff0c;银行…
文章目录什么是脱敏脱敏后带来什么问题解决方案一解决方案二具体实施方案一方案二存量数据处理什么是脱敏
如果你有申请过一些软件资质应该会被要求敏感数据进行加密比如密码不能明文用户的手机号身份证信息银行卡号信息等等都需要以加密的形式放在数据库中防止因系统漏洞导致被拖库黑客直接就能拿到这些信息给用户的人身财产安全带来严重的隐患。 脱敏实际就是加密这边分为两种类型
不可逆 如密码这种直接采用不可逆的加密方式可逆的 如手机号身份证银行卡这种信息需要密文存储但是需要时必须能解密。
都讲到这里了我们在多讲点相对于数据库而言日志被泄漏的可能性更大如果你的日志中大量打印了这些信息也一样泄漏之后会被坏人利用意味着除了数据库存储上需要做脱敏日志打印也是要做的。日志打印中可以采用简单暴力的方法直接屏蔽这些字段输出即可可以用*号直接代替不用考虑可逆性。
那么数据在传输的过程中是不是也会出现这种问题呢答案是肯定的当你的数据被中间人拦截的时候一样会泄漏这些数据。所以生产环境我们一定要使用https协议。所以前端发起请求时一般也会要求传输的数据需要加密。不过相对而言此处的数据传输上的要求没有对日志于数据库存储上来的严格一般只要求密码做个加密即可。
脱敏后带来什么问题
数据脱敏之后在数据库存储的就是个密文那么假如现在有个需求根据手机号模糊查询。你会发现对于这个密文完全行不通。 那么有没有解决办法呢
解决方案一
先分词再组合比如手机号 18850473300这样一个手机号我们可以将它分段然后按段进行加密后拼接起来存储后续接收的模糊查询字段按一样的方式分段加密然后查询比如分为344手机号可分为188、5047、3300这个也是有科学依据的一般人对数字的输入正常情况下都是3-4位数。
解决方案二
使用ShardingSphere 5.3 版本中的CharDigestLikeEncryptAlgorithm 算法进行like查询
具体实施
方案一
扩展mybatis的typeHandler但是这种方式对业务层有轻微的入侵。个人认为并不是太好。
参考扩展 开源组件原理比较简单我就不介绍了。
方案二
使用ShardingSphere组件这种方式对业务代码是0入侵
sharding-sphere-4.1.1
ShardingSphere 5.3
这两个地址的文档都可以看看
这个原理是通过代理数据源datasource拦截了sql处理中的prepareStatment阶段和resultset阶段的处理在预编译阶段从配置文件查询对应sql中存不存在需要配置的表和字段如果存在就将对应的参数进行加密在结果集中对对应的字段进行解密。
以下集成方案采用的是最简单粗暴的方式当然你也可以使用官方提供的starter集成只要代理数据源即可剩下的仅需进行配置。集成起来是非常简单的。
引入依赖
dependencygroupIdorg.apache.shardingsphere/groupIdartifactIdsharding-jdbc-core/artifactIdversion4.0.1/version/dependency做个简单的配置抽取
ConfigurationProperties(prefix user)
Data
public class UserProperties {private Datasource datasource;private Encrypt encrypt;Datapublic static class Datasource {private String type;private String driverClassName;private String url;private String username;private String password;}Datapublic static class Encrypt {//keytable , valuecolumnsprivate MapString, ListString tableFields;private String aesSecret;}
}Configuration
EnableConfigurationProperties(UserProperties.class)
MapperScan(basePackages com.xxx.xxx.xxx.mapper.user,sqlSessionFactoryRef userSqlSessionFactory)
public class UserDataSourceConfiguration {Bean(userSqlSessionFactory)SqlSessionFactory sqlSessionFactory(Qualifier(userDataSource) DataSource dataSource,ObjectProviderInterceptor[] plugins)throws Exception {MybatisSqlSessionFactoryBean sqlSessionFactoryBean new MybatisSqlSessionFactoryBean();sqlSessionFactoryBean.setVfs(SpringBootVFS.class);sqlSessionFactoryBean.setDataSource(dataSource);sqlSessionFactoryBean.setPlugins(plugins.getIfAvailable());sqlSessionFactoryBean.setTypeAliasesPackage(com.xxx.xxx.xxx.entity.user);ResourcePatternResolver resourceResolver new PathMatchingResourcePatternResolver();sqlSessionFactoryBean.setMapperLocations(resourceResolver.getResources(classpath:sql/user/**/*Mapper.xml));return sqlSessionFactoryBean.getObject();}Bean(userDataSource)public DataSource dataSource(UserProperties properties) throws SQLException {HikariDataSource dataSource new HikariDataSource();dataSource.setDriverClassName(properties.getDatasource().getDriverClassName());dataSource.setJdbcUrl(properties.getDatasource().getUrl());dataSource.setUsername(properties.getDatasource().getUsername());dataSource.setPassword(properties.getDatasource().getPassword());// 配置脱敏规则Properties props new Properties();props.setProperty(aes.key.value, properties.getEncrypt().getAesSecret());EncryptorRuleConfiguration encryptorConfig new EncryptorRuleConfiguration(AES, props);// 配置脱敏规则EncryptRuleConfiguration config new EncryptRuleConfiguration();this.setEncryptRuleConfiguration(config, encryptorConfig, properties);// 获取数据源对象return EncryptDataSourceFactory.createDataSource(dataSource, config, new Properties());}public void setEncryptRuleConfiguration(EncryptRuleConfiguration encryptRuleConfig,EncryptorRuleConfiguration encryptorConfig, UserProperties properties) {properties.getEncrypt().getTableFields().forEach((tables, fieldList) - {MapString, EncryptColumnRuleConfiguration columns Maps.newHashMap();fieldList.forEach(field - {//字段配置EncryptColumnRuleConfiguration columnConfig new EncryptColumnRuleConfiguration(,field, , aes);columns.put(field, columnConfig);//解密方式encryptRuleConfig.getEncryptors().put(aes, encryptorConfig);});//字段对应字段配置EncryptTableRuleConfiguration tableConfig new EncryptTableRuleConfiguration(columns);//表encryptRuleConfig.getTables().put(tables, tableConfig);});}
}配置文件
user:datasource:driver-class-name: com.mysql.cj.jdbc.Driverurl: jdbc:mysql://localhost:3306/user?serverTimezoneGMT%2B8autoReconnecttrueallowMultiQueriestrueuseUnicodetruecharacterEncodingutf8zeroDateTimeBehaviorconvertToNulluseSSLfalseusername: rootpassword: rootencrypt:aes-secret: hahahahhah # aes密钥tableFields: #加密字段配置 u_user: # 表 - user_account #表下的字段 - mobile- id_no- id_addressu_enterprise: #另一张表- bank_card_no #另一张表的字段- business_license_no
存量数据处理
当然不管那种方案下如果你是从0开始那么直接配置即可如果你已有存量数据那么你需要对这些存量数据进行清洗也就是存量数据你先得写个接口先进行加密不然直接跑起来会出错当然你也可以采用官方文档提供的方案使用辅组字段。个人感觉没什么必要这种东西又不会经常变来变去的。