由于某种缘由,须要去考虑数据脱敏的问题,可是既不想由于脱敏而影响数据的操做性,又须要对一些敏感信息进行可靠的保护。所以,正好解决了手头问题的我就开始研究各类脱敏手段、寻求最适合目前现状的脱敏解决方案。java
对于已经上线的业务,如何在不修改业务逻辑、业务SQL的状况下,透明化、安全低风险地实现无缝进行脱敏改造呢?mysql
Apache的ShardingSphere进入了个人视野,Apache ShardingSphere是一套开源的分布式数据库中间件解决方案组成的生态圈,它由Sharding-JDBC、Sharding-Proxy和Sharding-Sidecar(规划中)这3款相互独立,却又可以混合部署配合使用的产品组成。它们均可以提供标准化的数据分片、分布式事务和分布式治理功能,可适用于如Java同构、异构语言、容器、云原生等各类多样化的应用场景。算法
目前已上线业务,以前一直将明文存储在数据库中。由于某些缘由须要对已上线业务进行脱敏整改。为了解决这个问题,有三个问题须要考虑:spring
一、 如何对大量的历史数据须要脱敏处理。sql
二、 如何能在不改动业务SQL和逻辑状况下,将新增数据进行脱敏处理,并存储到数据库。数据库
3 、如何较为安全地实现业务系统在明文与密文数据间的迁移。apache
对静态业务脱敏有专业的脱敏手段,包括一些脱敏工具、亦或是使用SPL脚本或者存储过程对存量数据进行脱敏。因此,咱们此次主要研究如何不影响业务逻辑进行增量数据脱敏。编程
ShardingSphere提供的Encrypt-JDBC和业务代码部署在一块儿。业务方需面向Encrypt-JDBC进行JDBC编程。因为Encrypt-JDBC实现全部JDBC标准接口,业务代码无需作额外改造便可兼容使用。此时,业务代码全部与数据库的交互行为交由Encrypt-JDBC负责。业务只需提供脱敏规则便可。做为业务代码与底层数据库中间的桥梁,Encrypt-JDBC即可拦截用户行为,并在改造行为后与数据库交互。微信
Encrypt-JDBC将用户发起的SQL进行拦截,并经过SQL语法解析器进行解析、理解SQL行为,再依据用户传入的脱敏规则,找出须要脱敏的字段和所使用的加解密器对目标字段进行加解密处理后,再与底层数据库进行交互。ShardingSphere会将用户请求的明文进行加密后存储到底层数据库;并在用户查询时,将密文从数据库中取出进行解密后返回给终端用户。ShardingSphere经过屏蔽对数据的脱敏处理,使用户无需感知解析SQL、数据加密、数据解密的处理过程,就像在使用普通数据同样使用脱敏数据。
咱们这边能够直接用yaml配置来解释脱敏规则的配置。
是指DataSource的配置
spring: application: name: sharding-jdbc-examples main: allow-bean-definition-overriding: true shardingsphere: datasource: #数据源配置 names: ds ds: url: jdbc:mysql://127.0.0.1:3306/test1?useSSL=false&useUnicode=true&serverTimezone=UTC type: com.alibaba.druid.pool.DruidDataSource username: root password: root driver-class-name: com.mysql.cj.jdbc.Driver
是指使用什么加密策略进行加解密。目前ShardingSphere内置了两种加解密策略:AES/MD5。用户还能够经过实现ShardingSphere提供的接口,自行实现一套加解密算法。
encrypt: encryptors: encryptor_aes: type: aes #加解密器类型,可自定义或选择内置类型:MD5/AES props: aes.key.value: 123456* #属性配置, 注意:使用AES加密器,须要配置AES加密器的KEY属性:aes.key.value qualifiedColumns: t_user.password
用于告诉ShardingSphere数据表里哪一个列用于存储密文数据(cipherColumn)、哪一个列用于存储明文数据(plainColumn)以及用户想使用哪一个列进行SQL编写(logicColumn)。
tables: t_user: columns: passowrd: #logicColumn plainColumn: passowrd #plainColumn cipherColumn: newpassowrd #cipherColumn encryptor: encryptor_aes #加密器配置
当底层数据库表里同时存储了明文数据、密文数据后,该属性开关用于决定是直接查询数据库表里的明文数据进行返回,仍是查询密文数据经过Encrypt-JDBC解密后返回。
props: # 打印SQL sql.show: true check: table: metadata: true # 是否在启动时检查分表元数据一致性 enabled: true query: with: cipher: # 选择使用明文或者密文字段进行查询,true为密文 column: true
当配置好了这些信息后,就能够完成对数据的加密。
如今咱们利用以前作好的配置来进行一次简单的测试
测试完毕,咱们能够看出,经过用户提供的脱敏配置,数据找到了logicColumn,因而对逻辑列及其对应的明文数据进行脱敏处理。能够看出ShardingSphere将面向用户的逻辑列与面向底层数据库的明文列和密文列进行了列名以及数据的脱敏映射转换。
了解了数据新增的逻辑,那么数据查询、修改也是类似的原理。同时,查询的时候也能够选择使用明文仍是密文字段进行查询。
若是不涉及到旧业务改造,就能够免去plainColumn字段,直接使用cipherColumn便可。
已上线的任务,因为数据库存在大量的明文数据,如何对存量数据进行清洗,同时对新数据进行加密,在两套系统中无缝衔接,才是咱们要解决的问题。
数据清洗以前,咱们使用我以前的配置的内容,增删改查继续使用明文,在数据库只是新增字段存储密文数据,在对存量数据进行清洗以前不要擅自行动。
新增的数据已被Encrypt-JDBC将密文存储到密文列,明文存储到明文列;历史数据被业务方自行加密清洗后,将密文也存储到密文列。也就是说如今的数据库里即存放着明文也存放着密文。同时咱们随时能够经过配置来更换查询出的数据是明文仍是密文。
在校验完系统的可靠性和数据的正确性以前,不要直接删掉明文数据,以防万一。
因为安全审计部门要求,业务系统通常不可能让数据库的明文列和密文列永久同步保留,咱们须要在系统稳定后将明文列数据删除。
以后,咱们的脱敏表配置也能够进行改动了。(固然,特殊状况也能够留下明文数据进行备份,这个就要考虑到实际状况了)
tables: t_user: columns: passowrd: #logicColumn cipherColumn: newpassowrd #cipherColumn encryptor: encryptor_aes #加密器配置
固然,使用脱敏功能+分库分表功能,部分特殊SQL不支持,官方也提供了SQL规范供以查询规范地址
你们好,我是练习java两年半时间的南橘,下面是个人微信,须要以前的导图或者想互相交流经验的小伙伴能够一块儿互相交流哦。