一、前言近年来,无论是互联网公司还是传统行业,数据安全一直是企业绕不开的话题。数据加密是数据安全领域的核心模块之一。涉及客户安全数据或一些商业敏感数据的个人信息,如身份证号码、手机号码、卡号、客户号码等,需要根据相关部门的规定进行加密处理。这对安全部门和业务团队都提出了巨大的挑战。2.挑战在真实的业务场景中,相关业务开发团队往往需要根据公司安全部门的需求,实现和维护一套加解密系统,比如加解密SDK,或者加密提供的OpenAPI和解密服务。但在实际实施过程中,会发现业务代码入侵严重、业务线上化改造成本高、风险高等诸多令人头疼的问题。针对这些痛点,RainbowBridge提供了一整套透明的解决方案,实现业务代码零侵入,安全低风险的无缝加密改造。下面分析一下整个方案的实现原理。3.实现原理3.1RainbowBridge简介主要针对对RainbowBridge不熟悉的同学,这里做一个简单的介绍。一句话概括,RainbowBridge是一款基于ApacheShardingSphere二次开发的透明数据库中间件,通过数据分片、读写分离、影子库、加解密等能力增强了原有数据库。目前得物主要采用集中部署架构和分散部署两种方式。想进一步了解RainbowBridge的同学可以参考我之前写的一篇文章:得物数据库中间件平台《RainbowBridge》演进之路集中部署架构(Proxy模式)在ProxyMode中,加解密实现模块在Proxy中是内部完成,对上层应用完全透明。分散部署(JDBC模式)JDBC模式下,加解密实现模块在Rainbow内部完成,对上层应用完全透明。3.2核心名称解释在理解原理之前,先了解几个基本概念:名词解释逻辑列用于计算加密列的逻辑名,即业务代码中定义的SQL对应的列名。密文列用于存储加密后的数据。它是实际存在于数据库中的真实列名。明文列存储明文列。用于加密数据迁移过程中提供服务,数据清洗完成后可以删除。3.3加解密整体架构整个过程对上游业务应用是完全透明的,主要是通过RainbowBridge的内核模块解析SQL,然后找出需要加密的字段和使用的加解密算法进行加密根据加解密规则得到目标字段。加解密后,SQL变为与底层DB交互的SQL。RainbowBridge会对用户请求的明文进行加密存储在底层数据库中,当用户查询时将密文从数据库中取出解密返回给上游。通过屏蔽数据加密处理,用户无需感知SQL解析、数据加密、数据解密的过程,像使用普通数据一样使用加密数据。听起来有点抽象,下面举个例子更容易理解。--业务代码中的SQLselectphonefromt_userwherephone='10086'--SQLselectphone_cipherasphonefromt_userwherephone_cipher='xxx'经过RainbowBridge重写后在数据库中实际执行,其中phone为逻辑列,phone_cipher为密文列,彩虹桥内部加密10086,将where条件改为phone_cipher='xxx'。这里实际查询的是密文列,但是整个上层是不敏感的。对于业务,该字段为phone,实际查询数据库列为phone_cipher。3.4加密规则主要是用来告诉RainbowBridge逻辑表中哪一列用来存放密文数据(密文列),用什么算法加解密,哪一列用来存放明文数据(明文列)用户想要使用的列。列是用SQL编写的(逻辑列)。基于上面的例子,规则配置应该是这样的。这里的明文列可能比较难理解。我单独解释一下。明文列主要用于加密数据迁移过程中提供服务,数据清洗完成后可以删除。因为在线业务转型前,数据库中只存储明文,转型过程前几个阶段用于查询的列都是明文列。一般来说,明文列可以和逻辑列保持一致。3.5整体解决方案详解3.5.1线上新业务线上新业务比较简单,一切从零开始,不存在历史数据清洗问题。只需要配置规则,数据层不需要只保留一个密文列。3.5.2已上线业务转型已上线业务的转型过程相对复杂。由于业务已经在线上运行,数据库中必然存在大量的明文历史数据。需要解决的问题是历史数据如何加密清洗,增量数据如何加密,新旧数据系统之间如何实现业务的无缝透明迁移。下面我们把整个解决方案分成几个阶段来一一分析。第一阶段(步骤1~8)——增量数据双写(同时维护明文列和密文列),存量数据清洗步骤2~5主要是添加加密规则,让RainbowBridge可以实现doublewritingofincrementaldataWrite(同时维护明文列和密文列),此时查询仍然使用明文列。例如:--查询----业务代码中SQLselectphonefromt_userwherephone='10086'--这个阶段的查询不需要重写SQLselectphonefromt_userwherephone='10086'--更新----SQLupdatet_usersetphone='10000'whereid=1inthebusinesscode--SQLupdatet_usersetphone='10000',phone_cipher='xxx'whereid=1经过彩虹桥重写后实际进入数据库.Step6~8库存数据清洗主要借助数据平台(得物内部数据同步&订阅&迁移中间件)完成。密钥和对应的数据库列表信息由RainbowBridge发布。数据平台负责对所有的历史数据,按照相应的加密规则更新密文列。updatet_usersetphone_cipher='xxx',modify_time=modify_timewhereid=1andphone='10086'where条件加上phone='10086'是为了保证这个数据的明文在查询的时候没有被查询出来更新了其他上游修改。第二阶段(步骤9~11)——从确定文本栏切换到密文栏。股票数据清洗完成后,可以通过开关控制将查明文列切换为密文列(此处切换的粒度为列级)。对于密文列,如果在系统切换到密文列查询时系统报错,可以快速改回密文列进行恢复。整个过程只对少量查询造成损坏,不会产生脏数据。例如:--查询---业务代码中SQLselectphonefromt_userwherephone='10086'--SQLselectphone_cipherasphonefromt_userwherephone_cipher='xxx'--改写后在数据库中实际执行RainbowBridge-Update----SQLupdatet_usersetphone='10000'whereid=1inthebusinesscode--SQLupdatet_usersetphone='10000',phone_cipher='xxx'whereid实际去数据库执行后被RainbowBridge重写=1第三阶段(步骤12~14)-停止写入明文列,只写入密文列。将读取切换为密文列并运行一段时间后,可以通过配置停止对明文列的维护。此时读写都是密文列。例如:--查询---业务代码中SQLselectphonefromt_userwherephone='10086'--SQLselectphone_cipherasphonefromt_userwherephone_cipher='xxx'--改写后在数据库中实际执行RainbowBridge-Update----SQLupdatet_usersetphone='10000'whereid=1inthebusinesscode--SQLupdatet_usersetphone_cipher='xxx'whereid=1经过RainbowBridge重写后实际进入数据库。第四阶段(Step15)——数据层明文列清洗通过DML语句将明文列数据统一刷入无效数据即可。此处不建议使用DDL删除列。3.5.3大数据离线解密或风控团队日常会有一些抽取需求,分为T+1离线抽取和数据实时订阅两种。可通过数据平台提供相关解密能力。数据平台内部会调用RainbowBridgeOpenAPI获取密钥和加解密配置,解密后下发给下游。3.6Itemsnotsupported加密字段不支持查询不区分大小写功能;加密字段不支持比较操作,如:大于、小于、ORDERBY、BETWEEN、LIKE等;加密字段不支持计算操作,如:AVG、SUM、计算表达式。4、未来规划Key动态替换数据加密是为了防止一些敏感字段在出库时被泄露。如果密钥泄露,即使加密也是徒劳。因此,密钥支持动态更换,整个数据的安全级别将提升到一个更高的水平。具体实现方法其实比较简单,就是在密文中嵌入版本号信息,解密时根据版本号匹配对应的key,同步清理旧版本的密文列。salt加密的常规加密算法是将同一个明文加密后得到的密文是一样的,所以很容易被破解。如果我们在加密的时候加入一定的改变种子(加盐加密),那么加密后的密文会非常随机,很难通过凭证来破解。安全水平进一步提高。5.总结数据安全是一个非常严肃的话题。一旦发生数据泄露,尤其是涉及敏感信息的情况下,可能给客户和企业造成不可估量的损失,因此数据加密的必要性不言而喻。与传统的加解密方案相比,彩虹桥具有明显的优势。首先是自动透明的数据加密过程。用户无需关注加密过程的实现细节。他们只需要配置他们需要加密的列。RainbowBridge内置多种加密算法(MD5/AES/RC4等)可配置,可根据实际需要定制加密算法进行数据加密。特别是大部分场景都是针对线上业务的转型。RainbowBridge在转换过程中可以实现明文数据和密文数据的同步存储,通过配置决定是使用明文列还是密文列进行查询,可以在不改变业务查询SQL的前提下实现,在线系统对加密前后的数据进行安全、透明的迁移。在业务改造成本和密钥安全方面具有优势。
