https://blog.csdn.net/qq_31457665/article/details/115325042
前言
1.基础的环境介绍请移步ShardingSphere应用专题–4.1.1版本–sharding jdbc环境搭建(四)
你可以同时打开两个页面,避免因查找原始配置上下翻动。
2.ShardingSphere官方文档更新不及时,很容易踩坑。贴出的4.x版本文档实际是4.0.1版本的,如果你准备使用该版本可以参考官方文档。本文使用的是此时最新的正式版本4.1.1版本,配置与官方文档配置不同。事实上,源码中有非常详细的版本配置文档,本文也是参考4.1.1 tag的源码配置。
3.ShardingSphere各版本差异很大,甚至核心依赖的包名都不一样,使用时,一定要确认使用哪个版本,目前调研的结果:3.x、4.0.1、4.1.1、5.0.0-alpha都存在很大的配置差异
4.关于新项目的字段加密的业务场景分析参阅:
ShardingSphere应用专题–4.1.1版本–Sharding-JDBC 字段加密之新业务加密(九)
已上线业务改造
由于业务已经在线上运行,数据库里必然存有大量明文历史数据。现在的问题是如何让历史数据得以加密清洗、如何让增量数据得以加密处理、如何让业务在新旧两套数据系统之间进行无缝、透明化迁移。
重新搭建一套和生产环境一模一样的预发环境,然后通过相关迁移洗数工具把生产环境的存量原文数据加密后存储到预发环境,而新增数据则通过例如MySQL主从复制及业务方自行开发的工具加密后存储到预发环境的数据库里,再把重构后可以进行加解密的代码部署到预发环境。这样生产环境是一套以明文为核心的查询修改的环境;预发环境是一套以密文为核心加解密查询修改的环境。在对比一段时间无误后,可以夜间操作将生产流量切到预发环境中。此方案相对安全可靠,只是时间、人力、资金、成本较高,主要包括:预发环境搭建、生产代码整改、相关辅助工具开发等。除非无路可走,否则业务开发人员一般是从入门到放弃。
- 新增加密字段,启动定时器清洗加密字段
- 改造insert方法,数据加密存储进入加密字段–双写
- 改造select方法,优先查加密字段,如果加密字段没有清洗完成,使用明文字段(根据逻辑加密或不处理)–双查
- 所有数据都加密后,代码去除明文字段,去除双写双查逻辑
- 最后删除数据库明文字段
这个方法最大的问题是代码改造量大。成本高,测试面大,需要开发和测试精准找到所有加密字段的数据入口和出口,稍有遗漏就会造成bug
业务开发人员最希望的做法是:减少资金费用的承担、最好不要修改业务代码、能够安全平滑迁移系统。于是,ShardingSphere的脱敏功能模块便应用而生。可分为三步进行:
- 清空mydb测试库
- 对于现在的测试demo,需要对的bill_name字段进行脱敏处理.先造一些历史未加密的数据,共计6条
ALTER TABLE `mydb`.`bill`
ADD COLUMN `bill_name_cipher` varchar(255) DEFAULT '' COMMENT '账单名称(加密)' AFTER `bill_name`;
- 1
- 2
#打印sql
spring.shardingsphere.props.sql.show=true
#设置单次请求可适用的最大线程数,以决定是线程限制还是内存限制。增大该参数可提高数据库元数据加载速度(默认为1)
spring.shardingsphere.props.max.connections.size.per.query=3
spring.shardingsphere.datasource.names=master
spring.shardingsphere.datasource.master.type=com.zaxxer.hikari.HikariDataSource
spring.shardingsphere.datasource.master.driver-class-name=com.mysql.cj.jdbc.Driver
spring.shardingsphere.datasource.master.jdbc-url=jdbc:mysql://localhost:4406/mydb?characterEncoding=utf-8
spring.shardingsphere.datasource.master.username=root
spring.shardingsphere.datasource.master.password=111
spring.shardingsphere.encrypt.tables.bill.columns.bill_name.plainColumn=bill_name
spring.shardingsphere.encrypt.tables.bill.columns.bill_name.cipherColumn=bill_name_cipher
spring.shardingsphere.encrypt.tables.bill.columns.bill_name.encryptor=encryptor_aes
spring.shardingsphere.encrypt.encryptors.encryptor_aes.type=aes
spring.shardingsphere.encrypt.encryptors.encryptor_aes.props.aes.key.value=654321
#是否开启加密字段查询(默认为true)
spring.shardingsphere.props.query.with.cipher.column=false
1.逻辑字段名仍使用bill_name,这样对应的sql就不用变化
2.增加明文存储字段,即现在表中的bill_name字段,在新业务上线中,使用的配置中没有这个配置
3.加密字段指定为bill_name_chiper,在新业务上线中加密字段使用的就是原字段
4. query.with.cipher.column设置为false,这个时候加密字段仅仅在数据库中存在,逻辑字段名(1配置)查询会一直映射到plainColunm对应字段,不会使用cipherColumn字段,修改时会做双写。
- 插入
通过逻辑表名映射,改写sql,实现数据双写
明文仍然存储在bill_name_中,加密字段存储在bill_name_cipher字段
- 查询
查询只走明文
- 修改
同样是双写
我们还存在的原始数据的加密字段没有数据,需要将明文数据加密后存储在该字段,SharidngSphere目前并没有提供自动清洗的能力(这个肯定可以做的),不过这个很好实现,启动一个定时任务扫描清洗就好,就部分就不详谈了。
手动清洗后的数据:
修改配置
spring.shardingsphere.props.query.with.cipher.column=true
- 1
insert,update就不测试了,还是双写,测试下查询
这个时候,逻辑列的映射使用的时加密字段了
-
迁移中,原始明文数据没有做任何改动,这样就可以保证只要加密字段查询出现任何问题,就可以立马回滚。回滚仅仅需要将spring.shardingsphere.props.query.with.cipher.column的配置修改为false即可,这样又会切换到plainColumn查询
-
配合【服务治理】,可以做到动态刷新,无需重启服务。关于服务治理参阅:ShardingSphere应用专题–4.1.1版本–服务治理(十四)
加密列字段经过一段时间运行后,确认无问题,按照安全部门的要求,明文字段需要在数据库中删除了,但是我们的代码insert,和update还在双写,这个时候,仅需要将明文映射字段干掉,就可以完成整个最后阶段。
#打印sql
spring.shardingsphere.props.sql.show=true
#设置单次请求可适用的最大线程数,以决定是线程限制还是内存限制。增大该参数可提高数据库元数据加载速度(默认为1)
spring.shardingsphere.props.max.connections.size.per.query=3
spring.shardingsphere.datasource.names=master
spring.shardingsphere.datasource.master.type=com.zaxxer.hikari.HikariDataSource
spring.shardingsphere.datasource.master.driver-class-name=com.mysql.cj.jdbc.Driver
spring.shardingsphere.datasource.master.jdbc-url=jdbc:mysql://localhost:4406/mydb?characterEncoding=utf-8
spring.shardingsphere.datasource.master.username=root
spring.shardingsphere.datasource.master.password=111
spring.shardingsphere.encrypt.tables.bill.columns.bill_name.cipherColumn=bill_name_cipher
spring.shardingsphere.encrypt.tables.bill.columns.bill_name.encryptor=encryptor_aes
spring.shardingsphere.encrypt.encryptors.encryptor_aes.type=aes
spring.shardingsphere.encrypt.encryptors.encryptor_aes.props.aes.key.value=654321
spring.shardingsphere.props.query.with.cipher.column=true
-
插入及修改
-
查询
所有操作均不在涉及明文字段,这个时候,就可以在数据库删除明文字段了
总结
整个流程简单,透明。容错率高(可回滚)且成本低