#前言 每一个公司都会遇到数据安全性的问题,数据在当下甚至将来,其安全性只会愈来愈重要。而在大数据的环境下,数据多以集群存储,量大而复杂是大数据的一个重要特征,在这种状况下,数据的安全性方案该如何设计才能保证数据安全,同时保证集群负载小,对外透明度高呢?算法
目前的集群情况是上了Kerberos
,我想这是集群安全性的一个必要前提,即便你说集群位于公司内网,可是没上Kerberos谈安全和权限就没什么卵用。其次集群上了Sentry
,这是对权限管理的进一步增强,对Hive表可控制权限到列,对HDFS文件也可作具体权限控制。后端
一个公司大量的数据可能都是行为数据,因此并无太多须要保密的处理,须要加密的每每是敏感数据,好比身份证信息,某些ID等。HDFS在文件层面提供了透明加密机制,配置好后可建立加密区,经过API又可把数据从加密区恢复出来,在DataNode端直接查看Block块,数据是加密的,保证了安全性。可是它针对全部数据加密,虽然说对上层透明,安全好用,可是对集群压力大,不少不须要加密的数据作加密处理,是一种资源浪费。缓存
这里想要提到的方案就是针对Hive表字段加密
,一个表具有几十个字段,须要作保护的可能只有其中一两个,经过提供一个UDF,在数据入Hive表时,在须要加密的字段上调用,UDF对上层透明,可实现数据保护。在数据须要解密的时候,一样提供UDF用于解密,调用便可获得明文。安全
#方案 上面的一个想法,造就了不少种不一样方案,一个个尝试,一个个排除,最后发现回到原点,只有一种方案合适。尝试过的若干方案分两大类,按处理类型分为数据散列处理
和AES对称加密
。并发
##数据散列处理 散列处理是指Hash一类的处理,算法有md5, sha1, sha-256以及更高位数的散列算法。它有个显著特征是雪崩效应,原文稍有改变,算出来的值就会彻底不一样。Hash是一种摘要算法,同一种hash算法,针对不一样的输入,输出的位数是固定的,因此hash存在碰撞的可能。在用于数据加密的时候,若是存在hash碰撞,就会致使数据丢失,一个明文会覆盖另外一个明文。因此经过hash处理的话,就必须经过无碰撞或碰撞几率在可接受范围内的验证,同时敏感字段可能由于业务须要而在特定场景下须要还原,而hash不可逆,因此这种方案必须得作好明密文映射表。高并发
hash碰撞的几率可参考下图: oop
对于字段的结构,若是咱们很清楚而且在可穷举范围内的话,咱们能够选择一个盐,而后穷举全部可能,从而能够找到肯定无碰撞的盐。对于没法穷举的,只能验证一下碰撞几率是否在可接受范围内。大数据
###把散列算法布成服务,对外提供明密文访问的API 优点在于:加密
劣势在于:.net
###在UDF里作散列,控制盐的权限,而后单独起服务作映射表 一个字段对应一个盐,控制好盐的权限,好比把盐存入Hive表里,借用Sentry的权限控制实现表列的权限控制。在UDF里获取盐,而后实现加密,可是解密须要从映射表来,因此得专门起服务作映射表。
优点在于:
劣势在于:
以上是散列处理的两种具体方案,因为散列的不可逆,致使若是须要还原明文,它的代价就很是大,映射表的维护是极其麻烦的事情,并且备份和安全性都很差处理。但若是企业不要求还原,那这里的第二种方案不失为一个好的方案。
##AES对称加密 AES才是真正的加密算法,上述的散列只能是一种摘要算法,而非加密算法。
AES加密:一种对称加密的算法,加密和解密使用同一种秘钥。加密的过程是向量的移位运算过程,它会对输入进行16字节的划分,而后进行移位运算,解密则是其反向过程。
AES加密有不少不一样的模式,不一样模式的运算方式不同,有的模式还须要初始化向量。其中
CFB
和OFB
模式不会处理填充状况(即输入不满16字节的,是否填充为16字节)。因此AES的输出长度与输入长度是相关的,与秘钥长度无关。规律:输入是
16*n
字节,没有填充的状况下,输出和输入长度相同,有填充的状况下,输出为16*(n+1)
。若是输入不是 16字节的整数倍,是16*n
到16*(n+1)
的区间内,没有填充的状况下,输出和输入长度相同,有填充状况下,输出长度是16*(n+1)
在JDK里默认有AES 128位的加解密API,若是须要更高位数的,就须要下载额外的jar包,但通常128位平常加密就够使了。
在AES加密里,咱们能够把加密解密放在UDF里,只需作好秘钥Key的管理便可。
前期有个误解,觉得Sentry能控制UDF的使用权限,最后验证发现,Sentry其实只能控制UDF的建立权限,而不能控制使用权限。一个普通用户想要有UDF的建立权限,则必须给他关联上hive.aux.jars.path
里配置的目录下的jar包的ALL权限。
因此权限的控制只能放在Key的权限上,全部能取到Key的人,就具有了这个key所对应字段的加解密权限。前期觉得能对UDF和Key都作权限控制,这样分两级权限,把秘钥在后端作的更透明,能够增强权限的管理,有些人无需解密操做,就能够把解密的UDF不对他开放。结果发现只是咱们本身乐了一下~
在AES加解密的秘钥控制上,又有几种不一样的细分方案。针对秘钥的存储,分为Hive表存储
和KMS秘钥管理服务存储
。
###Hive表存储秘钥 这种方式比较简单(事实证实简单粗暴的每每是最好用的~),很好理解。经过建立多个列,不一样列对应不一样字段的秘钥,利用Sentry把权限控制到列,即把权限控制到了字段key的级别。
###KMS秘钥管理服务 它是Hadoop自己提供的一个秘钥管理组件,用于HDFS文件加密的,咱们能够利用它做为咱们秘钥管理的服务,它支持Kerberos认证和SSL,同时对权限可控制到具体key,权限管理上很是方便。
关于KMS秘钥管理服务,这里有单独的一篇文章作介绍,KMS秘钥管理服务
未完待续,下篇博客见 也说Hadoop敏感信息加密方案尝试(下)
欢迎小主们转载,但请注明出处:http://www.javashuo.com/article/p-cwsywivt-gw.html