数据加密:你应该知道的数仓安全
摘要:数据加密作为有效防止未授权访问和防护数据泄露的技术,在各种信息系统中广泛使用。作为信息系统的核心,GaussDB(DWS)数仓也提供数据加密功能,包括透明加密和使用SQL函数加密。
本文分享自华为云社区《你应该知道的数仓安全——加密函数》,原文作者:zhangkunhn 。
数据泄露防护
数据作为信息系统中的核心资产,其机密性、完整性和可用性必须得到保证,以避免数据被非法泄漏或非法篡改。当前数据泄露事件层出不穷,给个人和企业造成重大损失。
防止数据泄露可以有两种技术路径。一是权限管理,采用最小化授权原则对使用数据的用户和应用程序授权。另一种是数据加密,包括使用SQL函数加密和透明加密。 权限管理在你应该知道的数仓安全——默认权限实现共享schema一文中有所介绍。本文讨论透明加密,后续博文再谈谈SQL函数加密。
透明加密的应用场景
透明加密能够保障用户数据安全。更换磁盘、磁盘流出或者运维非法直接读取磁盘文件会绕过认证、权限管理和审计,从而导致数据泄露的风险。客户对业务数据有很高机密性要求时建议使用透明加密。
透明加密的原理
透明加密功能是对存在硬盘上的用户数据加密存储,对用户及上层使用SQL的应用不感知。透明的含义是指对客户来说是无感知的,仅需要创建GaussDB(DWS)集群时配置透明加密。目前支持行存表和列存表文件的加密存储,支持集群级别的透明加密配置。
集群级别的透明加密意味着集群中的所有库,库中的所有表都是加密存储。集群级别的透明加密还意味着需要在创建集群时进行配置,集群创建之后不可修改,既不能将非加密集群修改为加密集群,也不能将加密集群修改为非加密集群。
加密算法
透明加密核心是算法和密钥。我们采用AES-128算法,加密模式使用CTR。CTR流加密可以保证明文和密文长度相等,不会导致加密后数据存储空间膨胀。
密钥管理
使用华为公有云KMS服务管理,保证了用户的密钥安全。
加密密钥层次结构有三层。按层次结构顺序排列,这些密钥为主密钥(CMK)、集群密钥 (CEK)、数据库密钥 (DEK)。
- 主密钥保存在KMS中,用于给CEK加密。
- CEK用于加密DEK,CEK明文保存在集群内存中,密文保存在服务管理面中。
- DEK用于加密数据库中的数据,DEK明文保存在集群内存中,密文保存在服务管理面中。
密钥轮转
出于安全考虑,用户可以执行密钥轮转操作。密钥轮转只轮转集群密钥,不论转数据库秘钥。
透明加密的后续演进
集群级透明加密的优点是所有数据包括用户表和系统表都加密,适用于所有加密需求。一枚硬币的两面性告诉我们,优点也可能是缺点。对所有数据库对象加密会对数据导入和查询带来性能上的开销。
为解决此问题,后续考虑支持细粒度透明加密。比如可以支持表级透明加密,用户在创建表时指定属性为加密表,该用户表的数据会加密存储。用户可以在包含敏感数据的表中开启加密属性,在查询和使用过程中不感知加解密过程。由于加密粒度较小,对性能的影响也较小。
总结
透明加密是保障用户核心数据安全的有效手段。从使用场景和原理介绍了GaussDB(DWS)数仓的透明加密特性,指出了后续透明加密特性的研究方向。
加密算法介绍
密码学中密码算法可以分为三类:哈希函数、对称密码算法和非对称密码算法。
- 哈希函数
哈希函数又称为摘要算法,对于数据$$data$$,$$Hash$$函数会生成固定长度的数据,即$$Hash(data)=result$$。这个过程是不可逆的,即Hash函数不存在反函数,无法由$$result$$得到$$data$$。在不应保存明文场景,比如口令(password)属于敏感信息,系统管理员用户也不应该知道用户的明文口令,就应该使用哈希算法,存储口令的单向哈希值。
实际使用中会加入盐值和迭代次数,避免相同口令生成相同的哈希值,以防止彩虹表攻击。
- 对称密码算法
对称密码算法使用相同的密钥来加密和加密数据。对称密码算法分为分组密码算法和流密码算法。
分组密码算法将明文分成固定长度的分组,用密钥对每个分组加密。由于分组长度固定,当明文长度不是分组长度的整数倍时,会对明文做填充处理。由于填充的存在,分组密码算法得到的密文长度会大于明文长度。
流密码算法将明文逐比特与密钥流运算。流密码算法不需要填充,得到的密文长度等于明文长度。
- 非对称密码算法
非对称密码算法,又称为公钥密码算法。算法使用两个密钥:公钥和私钥。公钥向所有人公开,私钥保密。非对称密码算法应用于密钥协商、数字签名、数字证书等领域。
加密函数SQL接口
GaussDB(DWS)主要提供了哈希函数和对称密码算法。哈希函数支持sha256, sha384, sha512和国密sm3。对称密码算法支持aes128, aes192, aes256和国密sm4。
哈希函数
- md5(string)
将string使用MD5加密,并以16进制数作为返回值。MD5的安全性较低,不建议使用。
- gs_hash(hashstr, hashmethod)
以hashmethod算法对hashstr字符串进行信息摘要,返回信息摘要字符串。支持的hashmethod:sha256, sha384, sha512, sm3。
testdb=# SELECT gs_hash('GaussDB(DWS)', 'sha256'); gs_hash ------------------------------------------------------------------ cc2d1b97c6adfba44bbce7386516f63f16fc6e6a10bd938861d3aba501ac8aab (1 row)
对称密码算法
- gs_encrypt(encryptstr, keystr, cryptotype, cryptomode, hashmethod)
采用cryptotype和cryptomode组成的加密算法以及hashmethod指定的HMAC算法,以keystr为密钥对encryptstr字符串进行加密,返回加密后的字符串。
支持的cryptotype:aes128, aes192, aes256, sm4。
支持的cryptomode:cbc。
支持的hashmethod:sha256, sha384, sha512, sm3。
testdb=# SELECT gs_encrypt('GaussDB(DWS)', '1234', 'aes128', 'cbc', 'sha256'); gs_encrypt -------------------------------------------------------------------------------------------------------------------------- AAAAAAAAAADlzZYiNQK1uB+p1gza4Lu3Moj3HdP4E1uJmqfDYBaXDLMt7RZoE0YVx9h2dMRYBQ5fhFNqqM49sUkeS72o8kX5vWRQvfW3fuocGyp+b+lX9A== (1 row)
- gs_decrypt(decryptstr, keystr,cryptotype, cryptomode, hashmethod)
采用cryptotype和cryptomode组成的加密算法以及hashmethod指定的HMAC算法,以keystr为密钥对decryptstr字符串进行解密,返回解密后的字符串。解密使用的keystr必须保证与加密时使用的keystr一致才能正常解密。
testdb=# SELECT gs_decrypt('AAAAAAAAAADlzZYiNQK1uB+p1gza4Lu3Moj3HdP4E1uJmqfDYBaXDLMt7RZoE0YVx9h2dMRYBQ5fhFNqqM49sUkeS72o8kX5vWRQvfW3fuocGyp+b+lX9A==', '1234', 'aes128', 'cbc', 'sha256'); gs_decrypt -------------- GaussDB(DWS) (1 row)
应用举例
有个student表,有id,name和score三个属性。name可以使用哈希函数加密保存,score可以使用对称密码算法保存。
testdb=# create table student (id int, name text, score text); CREATE TABLE testdb=# insert into student values (1, gs_hash('alice', 'sha256'), gs_encrypt('95', '12345', 'aes128', 'cbc', 'sha256')); INSERT 0 1 testdb=# insert into student values (2, gs_hash('bob', 'sha256'), gs_encrypt('92', '12345', 'aes128', 'cbc', 'sha256')); INSERT 0 1 testdb=# insert into student values (3, gs_hash('peter', 'sha256'), gs_encrypt('98', '12345', 'aes128', 'cbc', 'sha256')); INSERT 0 1
没有密钥的用户即使拥有了select权限也无法看到name和score这两列加密数据。
testdb=# select * from student; id | name | score ----+------------------------------------------------------------------+-------------------------------------------------------------------------------------------------------------------------- 1 | 2bd806c97f0e00af1a1fc3328fa763a9269723c8db8fac4f93af71db186d6e90 | AAAAAAAAAAB26RmKZdGciLdOM1Z0sjsHg6Qh1b8taF3cY5KDVm+faJK5AT9tjufkr3Wogj3tIpFfiIEb6+miGqPHWcmKnFsArAMoBG9pPDawGs1Qze7xGg== 2 | 81b637d8fcd2c6da6359e6963113a1170de795e4b725b84d1e0b4cfd9ec58ce9 | AAAAAAAAAAB26RmKZdGciLdOM1Z0sjsHZOHH7URkyme6r8Hfh1k0UsVbgbREjFMkgB52w+7GtUGqGgUik07ghajSD9PMIDLd/49wBCVROm2/HSOw6jzbxA== 3 | 026ad9b14a7453b7488daa0c6acbc258b1506f52c441c7c465474c1a564394ff | AAAAAAAAAAB26RmKZdGciLdOM1Z0sjsHwv6p/OAfDUyVULAqpaHIrYJYMcqLmQSj3K/REyavfMoKB7hgUpEPXfHRutWur37bru68jjt5XcBHFBjZeMgowA== (3 rows)
拥有密钥的用户可以通过解密查看到加密数据。
testdb=# select id, gs_decrypt(score, '12345', 'aes128', 'cbc', 'sha256') from student; id | gs_decrypt ----+------------ 1 | 95 2 | 92 3 | 98 (3 rows)
总结
数据加密是防止未授权访问和防护数据泄露的有效技术。介绍了密码算法的基本原理和GaussDB(DWS)数仓的加密函数,包括哈希函数gs_hash,对称密码算法gs_encrypt/gs_decrypt。举例说明了加密函数的使用场景。
低调大师中文资讯倾力打造互联网数据资讯、行业资源、电子商务、移动互联网、网络营销平台。
持续更新报道IT业界、互联网、市场资讯、驱动更新,是最及时权威的产业资讯及硬件资讯报道平台。
转载内容版权归作者及来源网站所有,本站原创内容转载请注明来源。
- 上一篇
三大运营商日赚4亿?!移动+电信+联通+铁塔 < 腾讯
近日三大运营商先后发布了2020年经营报告。整体行业发展状况有所好转,至少无论营收还是利润都是正向增长,这对于爬坡转型中的运营商来说,做到这一点已经相当不容易。 但需要指出的是,这远没到“举杯相庆”的时候,以领头羊中国移动为例—— 2017年,中国移动营收7405亿元,净利润1143亿元; 2020年,中国移动营收7680亿元,净利润1078亿元。 三年时间过去了,中国移动营收才逐步回到原来的水平,但净利润水平还没有完全恢复! 所以,情况绝对没有好到部分媒体所说的“V型反转”,这何止是增量不增收啊,这简直是增量减收啊!反正绝对谈不上V型反转! 当前对于三大运营商而言,形势还相当严峻,传统通信业务的下行趋势仍未扭转,发展前景仍未明朗,包括5G,包括新兴业务,都没有形成可行的商业模式,云业务看起来很亮眼,无论是天翼云、沃云还是移动云,都实现了三位数的增长,但规模尚小,对大盘子的影响力还相对较弱。 此外,运营商在很多新的尝试尚需时间和市场去进一步检验,在这样的情况下,去吹捧V型反转,这对未来发展绝对不是好事。 此外,我还非常反感部分媒体总是以“日赚4亿”为噱头来报导,事实上,三大运营商日赚4...
- 下一篇
Golang 并发编程实践
人是一种高并发的物种,细品。 初识 对 Go 语言的第一印象就是其原生地支持并发编程,而且使用的是协程,比线程更加轻量。 关于进程、线程和协程的区别 进程是“程序执行的一个实例” ,担当分配系统资源的实体。进程创建必须分配一个完整的独立地址空间。进程切换只发生在内核态。 线程:线程是进程的一个执行流,独立执行它自己的程序代码,是程序执行流的最小单元,是处理器调度和分派的基本单位。一个进程可以有一个或多个线程。 协程:协程不是进程或线程,其执行过程更类似于子例程,或者说不带返回值的函数调用。在语言级别可以创建并发协程,然后编写代码去进行管理。Go 将这一步承包下来,使协程并发运行成本更低。 Go 实现最简单的并发 for i := 0; i < 10; i++ { go func(n int) { fmt.Println(n) }(i) } 项目实践 最近有个项目需要同时调用多个 job,并要等待这些 job 完成之后才能往下执行。 串行执行 job 最开始,我们拥有一个执行 job 的方法,并且串行执行所有的 job: func buildJob(name string)...
相关文章
文章评论
共有0条评论来说两句吧...
文章二维码
点击排行
推荐阅读
最新文章
- Docker使用Oracle官方镜像安装(12C,18C,19C)
- Springboot2将连接池hikari替换为druid,体验最强大的数据库连接池
- SpringBoot2全家桶,快速入门学习开发网站教程
- Windows10,CentOS7,CentOS8安装MongoDB4.0.16
- CentOS8,CentOS7,CentOS6编译安装Redis5.0.7
- SpringBoot2配置默认Tomcat设置,开启更多高级功能
- CentOS7,CentOS8安装Elasticsearch6.8.6
- CentOS6,CentOS7官方镜像安装Oracle11G
- Windows10,CentOS7,CentOS8安装Nodejs环境
- Linux系统CentOS6、CentOS7手动修改IP地址