暂无图片
暂无图片
1
暂无图片
暂无图片
暂无图片

PostgreSQL数据库透明数据加密之PG中的TDE


王硕
中国PG分会认证专家
PostgreSQL资深内核研发工程师,他为完整数据库加密,Oracle兼容功能,PostgreSQL监控工具,PostgreSQL即时编译等做了很多工作

前言

       最近一段时间,一直在和PostgreSQL国际社区合作开发透明数据加密(Transparent data encryption),研究了一些密码学相关的知识,并利用这些知识和数据库相结合。本系列共分为3篇文章,前两篇分别介绍了加密算法和密钥管理(关注文末二维码,往期文章不迷路)。本文是最后一篇,将介绍PG中的TDE。


一、什么是透明数据加密

        透明数据加密,从字面上来说,可以分为三部分,数据,加密,透明。数据,这里不用过多解释,用户需要保护的明文数据。加密,相信大家也清楚,信息安全一直伴随着世界的发展,加密是信息安全的一种重要手段,常用加密方法目前可以分为流密码加密、分组加密以及公钥加密3种。透明,指的是用户无感知,这是对加密行为的描述。

        一般涉及到加密码学相关话题时,我们首先要清楚面对的安全威胁是什么?


二、当前数据库数据面临的威胁模型



  1. 不恰当的权限 很多应用或者软件在使用过程中,往往因为使用的便利,将不必要的权限赋予用户;其次,未及时清理无效的用户(比如,离职员工),同样会造成信息的泄露。大多数应用软件不会对于DBA和开发人员进行过多的限制,这同样有数据丢失的风险。权限赋予策略、三权分立或者数据库审计都是有效防范此类威胁的重要手段。

  2. SQL注入攻击 SQL注入攻击一直是数据库面临的重大风险之一。随着B/S模式应用开发的发展,使用这种模式编写应用程序的程序员也越来越多。但是由于程序员的水平及经验也参差不齐,相当大一部分程序员在编写代码的时候,没有对用户输入数据的合法性进行判断,使应用程序存在安全隐患。用户可以提交一段数据库查询代码,根据程序返回的结果,获得某些他想得知的数据。合理的软件架构设计以及合法的SQL审计,是防范此类威胁的有效方法。

  3. 恶意攻击 攻击者可以通过网络窃听、木马攻击等方式影响数据库,造成数据丢失风险。很多厂商往往会因为性能或者资源等原因,没有开启网络传输加密,从而造成数据窃听风险。其次,恶意攻击者可以通过木马病毒等措施,感染合法用户设备,从而窃取数据,造成数据丢失。提高安全措施,比如开启防火墙,开启网络传输加密等,其次加强数据库审计可以方法此类威胁。

  4. 弱审计跟踪 由于资源的消耗、性能的下降,很多厂商关闭或者开启较少功能的审计跟踪,这会导致恶意的管理员对于数据的非法侵入。其次,由于审计之后的限制操作比较难以实现,比如对于DBA和非法侵入就难以区分,从而导致审计之后的操作难以防御攻击。网络设备审计是目前最有效的审计方案。

  5. 不安全的存储介质 存储介质存储窃取的风险,其次备份存储存储安全设置较低的因素,这都会造成数据丢失。提高物理介质的保护,加密用户数据,加强所有数据存储的安全设置能够防范此类威胁。

  6. 不安全的第三方 随着云时代以及5G的到来,更多的厂商将数据存储到云端。这其实存在第三方信任问题。如果第三方存在恶意管理员,非法窃取或读取敏感数据;或者提供存在安全隐患的服务器,这都会造成数据丢失。选择可信任的第三方,加密用户数据,可以避免不安全的第三方威胁。

  7. 数据库漏洞或者错误的配置 随着现代数据库软件的功能增多,复杂的程序很可能会存在安全漏洞,而且很多厂商为了保证系统的稳定性不愿意进行版本升级,同样数据面临很大的泄露风险。其次,安全设置不足也存在很高的风险。这里的安全配置不仅仅指的是数据库层面,操作系统层面也需要加强安全配置。定期修复数据库漏洞,加强安全配置。

  8. 有限的安全专业知识和教育 据统计,大约有30%的数据泄露事件是由人为疏漏造成的,所以安全教育同样需要加强。定期进行安全专业知识讲座,提高安全防范意识。

         综上所述,目前数据加密能够应对的威胁有有不安全的存储介质,不安全的第三方。而我们知道数据库不仅需要安全因素的考量,同时需要兼顾性能、稳定、易用的因素。那么如何设计数据加密?

三、加密等级

       首先我们回顾一下PostgreSQL整体架构:

        通过整体架构来看,我们可以将加密分为6个等级。从上图可以看到,客户端和服务端进行交互,用户数据自客户端起,由服务端接收,并写入到服务端缓存中,再刷入到磁盘内。而PostgreSQL存储物理结构为:集群-->表空间-->数据库-->关系对象。由此我们可以将数据库分为6个层级进行加密,分别是,客户端加密,服务端加密,集簇级加密,表空间级加密,数据库级加密以及表级或对象级加密。下面对这6个层级进行分别阐述:

  1. 客户端加密,由用户生成密钥,对字段进行加密;

    1. 优点:在某种程度上能够防范DBA以及开发人员;加密粒度小,加密数据量可控。现有的加密插件pgcrypto可以客户端的数据加密功能。

    2. 缺点:使用成本较高,需要调整现有应用系统,对数据插入语句进行修改;其次由于从数据生成开始加密,等于是缓存级加密,性能较差,索引无法使用。

  2. 服务端加密,建立加密类型,对字段进行加密;

    1. 优点:使用成本相对于客户端加密较低,仅需要对数据库进行调整,无需修改应用程序,加密粒度小,加密数据量可控。

    2. 缺点,同样是缓存级加密,性能较差,索引无法使用。

  3. 集簇级加密,对整个集簇进行加密,初始化时确定集簇是否加密;

    1. 优点:架构简单,使用成本低,操作系统缓存级加密(数据缓存刷入、读取磁盘时加解密),性能相对较好;

    2. 缺点,加密细粒度大,所有集簇内对象都会加密,会造成性能下降。

  4. 表空间级加密,对某一个表空间设置加密属性,所有在加密表空间内都默认加密;

    1. 优点:架构简单,使用成本低,操作系统缓存级加密,性能相对较好,加密细粒度降低,能够更好的控制加密数据量,有利于数据加密效率;

    2. 缺点:表空间在PostgreSQL的概念不够明确,用户容易误解,其次在备份管理等方面使用成本较高。

  5. 数据库级加密,指定某个库为加密库,所有在加密库中的对象默认加密;

    1. 优点:架构简单,使用成本低,操作系统缓存级加密,加密细粒度降低,数据加密效率高;

    2. 缺点:加密细粒度相对较大。

  6. 表级加密或者文件级加密,指定某个对象加密;

    1. 优点:架构简单,使用成本低,操作系统缓存级加密,加密细粒度进一步降低,数据加密效率高;

    2. 缺点:密钥管理成本较大,开发复杂度较高。其次当需要加密的对象较多时,使用成本较高。

         这里解释以下为什么缓存级加密无法建立索引的原因:建立索引的目的是提高数据建索效率,而加密的原因是保护敏感数据。

  • 那么如果我们在缓存级加密,如果建立索引,这里也需要分为两种情况,基于明文建索引或基于密文建索引。

    • 基于明文建索引则需要对明文进行解密,建立索引,后对索引加密,但这样加解密次数过多,会引起性能下降,其次索引本身的顺序也会造成一定的信息泄漏。

    • 基于密文建索引则索引无法有效对数据排序,也就难以起到快速减速的能力。

  • 那如果不对索引加密,则会对数据安全产生影响。

        上面提到了缓存级和文件系统级加密,接下来从存储架构上来看:

         由上图可知,我们可以分为三个等级,数据库缓存级,操作系统缓存级以及文件系统级:

         数据库缓存级加密:上述的等级1、2都是数据写入缓存时已经加密,缓存级加密,数据检索时解密,性能最差;操作系统缓存级:等级3、4、5、6都是在PostgreSQL数据刷写磁盘是加密,数据加载时解密,性能相对较好;文件系统级:数据库自身无法实现,需要使用文件系统加密,数据库不可控。

         那对于数据库来说应该如何选择?虽然加密是一种很好的数据安全保护手段,但是如何加入到数据库中还需要进行整体性考虑。在对数据库进行加强时,我们需要考虑:

  • 开发成本

  • 安全性

  • 性能

  • 易用性

         社区经过多次讨论,目前由于设计难易度以及开发成本的角度,选择了集簇级加密作为TDE的第一个方案。

         我们都知道,常用加密目前主要有流式加密、分组加密、公钥加密三种。在使用加密算法的时候,应注意:

  • 加密方法由两部分构成,密钥以及加密算法。通常我们建议使用国际公开、认证的加密算法。

  • 密钥的保护等同于明文的保护。

         如何进行加密我们之前分为两篇文章讲述:加密算法的选择以及密钥的管理。

、数据库中如何选择加密模式

         开发成本:使用openssl自带的加密算法,加密算法开发成本低;其中除ECB外都需要额外的使用向量或计数器,开发成本相当;由于CBC和ECB需要进行填充数据,考虑到WAL流复制过程,不推荐使用。最优选择为CFB,OFB和CTR。 安全性:ECB不予考虑,其他皆可。 性能:由于是在刷写磁盘时进行加解密,那么考虑到读取和写入的并行要求,以及加密算法的性能,CTR mode是最优选择。 易用性:在此不需要考虑。

         以上,从各个层面来说,CTR都是最优的加密mode,社区同样选择了CTR mode作为加密模式。

数据库中如何使用CTR mode

         要添加CTR mode到数据库,需要了解CTR的加密过程。 从上面的加解密流程可以知道,CTR加解密时需要4部分共同协作,明/密文,算法,计数器,密钥。

  • 算法本身是调用openssl的CTR mode,所以这里无需开发,只需要熟读openssl的文档即可。

  • 明/密文,根据加密等级的介绍,数据库是将缓存刷入磁盘时进行加密的,也就是说将会对page进行加解密,其大小为8192 bytes,正好是加密块的整数倍;其次在考虑流复制的特殊性,我们也会对recode进行加解密。

  • 计数器,根据NIST的加密算法说明,我们可以知道,这里的计数器不要求强随机,只要是保证不重复即可。其次,计数同样需要保存在数据库中。因此考虑使用page页上的LSN来作为计数器的一部分,(这里要说明的是,LSN是存在重复的可能性。社区目前有人提供一个新的补丁来防止LSN重复的可能),其次使用文件名以及也的顺序作为其中的一部分。以此来保证其唯一性。

  • 密钥,密钥的保护等于密文的保护。所以密钥如何生成、管理是非常重要的。将由下面这个章节进行说明。


、TDE的密钥管理方法

        以上密钥管理方法没有明确不推荐的情况下,都是可以使用的。笔者和国际社区沟通的过程中推荐的是,基于口令的密钥生成,使用KEK存储密钥,Diffie-Hellman密钥交换的方案。

        当前国际社区经过多轮讨论后,目前有两种方案:2层密钥管理和3层密钥管理,下面对其进行介绍:

2层密钥管理:

        2层密钥管理使用的是,基于口令的密钥生成,使用KEK存储密钥以及使用密钥分配中心3者的结合,架构体系如下图:

         这和之前讲到的基于口令的密码很相似,不过数据加密密钥将会存储到数据库服务器,这有别于基于口令的密码存储到外部服务器。

3层密钥管理:

         这里使用的是,基于口令的密钥生成,HKDF,使用KEK存储密钥以及使用密钥分配中心4者的结合,架构体系如下图:

  1. 用户输入口令;

  2. 系统生成随机数,与用户口令进行hash计算,得到密钥加密密钥;

  3. 随机数存储至安全处;

  4. 系统生成随机数作为MDEK(master data encryption key),存储至安全处;

  5. 使用MDEK和加密文件信息得到数据加密密钥;

  6. 使用数据加密密钥对数据进行加解密。

          目前密钥管理还有一定争议,我个人比较赞同第二种方式,为后期更小加密细粒度做准备。

、其他数据库TDE方案对比

          做任何事情都不是闭门造车,现阶段,很多数据库已经支持了TDE,我们对此进行对比,以此来确定最优的方案:

Oracle

    • 加密等级:Tablespace-level,Column-level

    • 加密算法:AES,3DES

    • 密钥管理:主密钥和数据加密密钥

SQL Servel

    • 加密等级:Database-level

    • 加密算法:AES,3DES

    • 密钥管理:系统密钥,主密钥,系统证书,数据加密密钥

DB2

    • 加密等级:Database-level

    • 加密算法:AES,3DES

    • 密钥管理:主密钥和数据加密密钥

MySQL

    • 加密等级:Tablespace-level,Column-level

    • 加密算法:AES,3DES

    • 密钥管理:OASIS Key Management Interoperability Protocol (KMIP) TC

、未来的数据安全畅想

          现在5G的来临,云时代的来临,我想未来的IT架构,更多的都是基于云的设计。更多的数据存储在云上,那么云厂商如果对用户数据窃取、分析,那都会严重侵犯我们的隐私。之前在威胁模型中也说到的恶意DBA和开发人员,他们往往具有较高的数据库权限,哪怕没有权限,他们如果有读取缓存的方法,那么数据同样会泄露。那么如何保护我们的数据呢?

同态加密:

         同态加密(Homomorphic Encryption)是很久以前密码学界就提出来的一个Open Problem。早在1978年,Ron Rivest, Leonard Adleman, 以及Michael L. Dertouzos就以银行为应用背景提出了这个概念。

        一般的加密方案关注的都是数据存储安全。即,我要给其他人发个加密的东西,或者要在计算机或者其他服务器上存一个东西,我要对数据进行加密后在发送或者存储。没有密钥的用户,不可能从加密结果中得到有关原始数据的任何信息。只有拥有密钥的用户才能够正确解密,得到原始的内容。我们注意到,这个过程中用户是不能对加密结果做任何操作的,只能进行存储、传输。对加密结果做任何操作,都将会导致错误的解密,甚至解密失败。同态加密方案最有趣的地方在于,其关注的是数据处理安全。同态加密提供了一种对加密数据进行处理的功能。也就是说,其他人可以对加密数据进行处理,但是处理过程不会泄露任何原始内容。同时,拥有密钥的用户对处理过的数据进行解密后,得到的正好是处理后的结果。

        如果不是很理解他的概念,那么我们可以看下图:

图片来自于知乎--刘巍然-学酥

          同态加密你可以想象,DBA和开发人员或者恶意的云管理员,他们就像是操作工人(攻击者),必须带着手套在加锁的盒子里(加密算法)处理金子,没有钥匙(密钥)打不开,如此,他们是无法窃取金子(数据)的。

          那么未来如何使用同态加密呢?

图片来自于知乎--刘巍然-学酥

          Alice通过Cloud,以Homomorphic Encryption(以下简称HE)处理数据的整个处理过程大致是这样的

  1. Alice对数据进行加密。并把加密后的数据发送给Cloud;

  2. Alice向Cloud提交数据的处理方法,这里用函数f来表示;

  3. Cloud在函数f下对数据进行处理,并且将处理后的结果发送给Alice;

  4. Alice对数据进行解密,得到结果。

          那么为什么现在还没有大规模应用呢?根据IBM团队的研究,直到2016年,该技术都还存在性能瓶颈,巨大的性能开销让人无奈至极。 同态加密的发明者克雷格•金特里(Craig Gentry)带领IBM的研究团队进行了一系列同态加密尝试。最初的时候,同态加密的数据处理速度比明文操作慢“100万亿倍”,后来在16核服务器上执行,速度就提升了200万倍,但还是比明文操作慢很多。因此,IBM继续改进HElib,其发布在GitHub上的最新版就重新实现了同态线性变换,性能得到极大提升,速度加快了15-75倍。国际密码学研究协会的一篇论文中,IBM密码研究团队的谢•哈勒维(Shai Halevi)和纽约大学库朗数学研究所教授维克多•舒普(Victor Shoup,同时供职IBM苏黎世研究实验室)阐述了速度提升的方法。

         所以当前同态加密的性能无法满足正常需要,如果商用到数据库层面,我认为还需要密码学家的进一步研究。请大家期待吧。

、写在最后

         以上所有方法都是软件层面的操作,目前关于数据加密其实涌现了很多硬件解决方案,比如FPGA卡加解密,以提高其性能;还有Intel的基于可信执行环境技术(Trusted Execution Environment)的可信计算等等。加密也仅仅是数据库安全的一小部分,更多的内容需要大家的共同努力,也希望在未来能够看到更多的人从事到数据库安全领域当中。

最后修改时间:2019-11-06 10:57:54
文章转载自开源软件联盟PostgreSQL分会,如果涉嫌侵权,请发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

评论