为何要作加密服务,最近GDPR对我的数据查的很严,若是违反规定,罚款是很大的,大部分开发的同窗是没太多安全意识的,说不定哪天由于系统漏洞致使数据被泄露出去了。
为了不系统漏洞致使敏感数据被泄露,须要对源头即数据库的数据进行加密,加密以后即便因系统漏洞致使被脱库,泄露的也是加密数据,不是用户的真实数据。html
加密范围很大,包括数据库、缓存、其它存储中间件,还有传输过程,为了简化问题,咱们今天只讲数据库字段存取的加密。算法
另外为了简化问题,咱们今天所讲方案都是基于如下的用户表设计:
字段 类型 说明
id int 主键
name varchar(50) 用户名称
mobile varchar(50) 手机数据库
回到正题,若是要设计一个加密服务,你们会怎么设计呢? 任何一个系统的设计都必需要代入业务场景中,咱们从用例开始分析具体的业务场景:
用例分2类:
一类是针对业务系统的,每一个业务系统的需求就是加密和解密。缓存
数据库字段在其上的操做有:查询,添加、更新、删除,对于加密服务来讲,须要加密指定的字段,而且能够对其进行解密;另外针对加密字段还能够查询,这个是一个难点,下面再讲。安全
对于系统管理员,也就是安全的同窗来讲须要管理哪些应用在加密,即须要颁发密钥后,应用才能够加密;另外出于安全考虑,还须要按期变动应用密钥。 另外一个就是解密的受权管理,即应用A加了密以后,不是全部应用均可以解密的,须要管理加密方和解密方的受权关系。
加密算法选择app
由于还要解密,能够选择强度比较高的对称加密算法,如AES256等,这里不专门讲加密算法,有兴趣的同窗能够百度下。
数据的存放格式设计加密
关键的问题来了,加密后的数据怎么存, 直接用加密算法,如AES256加密后存放到数据库字段就好了吗? 实际的场景是加密方可能有多个,即加密的内容,多是应用A,也多是应用B加密的,系统上要能区别出来; 另外就是密钥的变动,应用A的密钥会变,不一样时期多是不同的,一个表的数据可能由多个密钥加密的,即上面的用户表,可能第一行的mobile是由id为1的密钥加密的,而第二行是由id为2的密钥加密的,这2种状况都须要能被解密出来 。 因此加密字段不只要存放加密后的内容,还要存放一些元信息:哪一个应用加密的,哪一个密钥加密的。
相关表设计
应用表 设计
字段 类型 说明
id int 主键
name varchar(50) 应用名称code
应用密钥表 htm
字段 类型 说明
id int
自增主键
app_id int 应用id
key varchar(64) 密钥
version varchar(4) 版本号
algrithom varchar(64) 加密算法
加密内容格式,咱们建议要包含上面信息,便可以把应用密钥表的id和加密后的内容存放一块儿,如:密钥id + ^ + 加密内容。 解密时,先解析获得密钥表的id和加密内容,根据id获得密钥,而后进行解密,这样每次变动密钥以后,历史数据不受影响。
加密字段查询
一个字段加密以后,还要根据其查询,这样的场景应该仍是很多的,像用户表的手机号。 咱们首先说下问题在哪里,在某个时间密钥换了,即user表的mobile可能被N个密钥加密,即总共2行数据,可能第一行是用密钥A加密的,第二行倒是用密钥B加密的,先将原文加密去查询的话,用哪一个密钥呢? 这里的问题是,由一个输入得不到一个肯定的输出,因此咱们的问题就是如何由一个肯定的输入在任什么时候间获得不变的输出。 一、等值查询 最简单的方案就是加字段,即在user表再加个mobile_hash字段,这里存放将mobile字段hash后的值,hash算法能够选md5或sha256,这样在任什么时候候由输入能够获得一个肯定的输出;但这里有个风险,md5算法可能碰撞,根据HASH查询出来以后可能不是输入的手机号,业务上须要解密下是否是和原文相等。 固然也能够不加字段,能够将hash后的值存放到mobile的前面,每次查询用like进行左前缀匹配。 二、须要作like查询 这里方案比较复杂,也比较烧脑,有一篇论文讲的比较详细,有兴趣的同窗能够看下:https://www.jiamisoft.com/blog/5961-kuaisuchaxunshujukujiami.html 。