HDFS加密存储,在CSDN上可以看到很多的前辈整理的博客,但是按照https://blog.csdn.net/linlinv3/article/details/44963429所介绍的那样在我的环境并不能达到预期效果,将自己对hdfs加密的理解和实际操作做一个简单整理。
首先,hdfs的加密方式为AES加密,先对AES加密做一个简单了解。
对称加密算法:AES加密算法
下面简单介绍下各个部分的作用与意义:
密钥K
用来加密明文的密码,在对称加密算法中,加密与解密的密钥是相同的。密钥为接收方与发送方协商产生,但不可以直接在网络上传输,否则会导致密钥泄漏,通常是通过非对称加密算法加密密钥,然后再通过网络传输给对方,实际中,一般是通过RSA加密AES的密钥,传输到接收方,接收方解密得到AES密钥,然后发送方和接收方用AES密钥来通信。
或者直接面对面商量密钥。密钥是绝对不可以泄漏的,否则会被攻击者还原密文,窃取机密数据。
AES加密函数
设AES加密函数为E,则 C = E(K, P),其中P为明文,K为密钥,C为密文。也就是说,把明文P和密钥K作为加密函数的参数输入,则加密函数E会输出密文C。
AES解密函数
设AES解密函数为D,则 P = D(K, C),其中C为密文,K为密钥,P为明文。也就是说,把密文C和密钥K作为解密函数的参数输入,则解密函数会输出明文P。
HDFS Encryption Zone加密空间,即HDFS透明加密,是一种端到端的加密模式,其中的加/解密过程对于客户端来说是完全透明的。数据在客户端读操作的时候被解密,当数据被客户端写的时候被加密,所以HDFS服务端本身并不是一个主要的参与者。形象地说,在HDFS服务端,你看到的只是一堆加密的数据流。
这个功能作用就是保证处于加密空间内的数据不被非法查询,只有经过认证的客户端才能查看解密内容。
准备知识
Encryption Zone是HDFS中的一个抽象概念,它表示此空间的内容在写的时候会被透明地加密,同时在读的时候,被透明地解密;用户往HDFS上存储数据的时候,无需用户做任何程序代码的更改(意思就是调用KeyProvider API ,用于在数据存入到HDFS上面的时候进行数据加密,解密的过程一样)。这意味着数据加密和解密由客户端完成的。HDFS不会存储或访问未加密的数据或数据加密密钥(由KMS管理)。
具体到细节:
DEK使用hadoop key命令来创建,EZ key使用keytool –genkey来生成。(?待定)
Client向NN(HDFS组件的NameNode服务进程)请求在HDFS某个加密区新建文件;
NN向KMS请求此文件的EDEK,KMS用对应的EZ Key生成一个新的EDEK发送给NN;
NN 发送此EDEK给Client;
Client发送EDEK给KMS请求解密,KMS用对应的EZ Key将EDEK解密为DEK发送给Client;
Client拿到对应的DEK后对文件进行加密和解密
综上所述可知:HDFS Server端的进程(NameNode,DataNode)本身并不参与hdfs区域的加密和解密,Namenode所做的事情只是向KMS请求获取EDEK后将它发送给hdfs client,以便于client将EDEK解密之后,对实际的hdfs区域进行加密与解密,hdfs的加密与解密都只在hdfs client端完成。
通过ranger快速连接,选择“Ranger Admin UI”,以keyadmin/keyadmin登录;点击Encrytion tab -> 选择Key Manager; Select Service= 集群名+ _kms; 点击Add New Key按钮,添加key name为key1的key。
修改hdfs配置,启用Ranger for hdfs。
通过界面创建hdfs加密区
若此处提示RemoteException,是因为hdfs被拉进了对应的黑名单,创建如下策略,给hdfs对应的权限,保存即可,请特别注意不要给予解密权限(Decrypt EEK)。
Hdfs提示权限问题直接将hdfs对应路径的权限修改为777即可。
由以上可知,如果使用者未给对应的用户赋予Decrypt EEK的权限,对应的用户是无法往加密区里面读或者写东西的。这一点很好理解,对于别的用户,即使可以拿到EDEK,但是没有解密已加密的密钥的权限,即无法得到真正的密钥,所以无法对文件进行加密或者解密操作。
创建本地用户test。
[root@node1 hdfsencrytest]# useradd test
利用ranger,以keyadmin用户登录ranger,点击aaa_kms,先删除掉之前为hdfs分配的policy1,不然后续的policy创建可能不成功。再为test用户创建对应的policy。
Test用户可以进行对加密区的一些列操作,如下所示
用如下命令查看加密区与非加密区域的文件,观察明文与密文的对比。可见加密区aaa.txt密文显示,非加密区明文显示,至此,hdfs加密配置与验证均完成。
关于"通过ranger快速连接,选择“Ranger Admin UI”,以keyadmin/keyadmin登录;点击Encrytion tab -> 选择Key Manager; Select Service= 集群名+ _kms; 点击Add New Key按钮,添加key name为key1的key"即在Ranger UI里面创建key1这一步,究竟创建的是EZ key还是DEK?
参考前辈的文章和官网介绍,利用hadoop kms的方式来创建hdfs加密区,都会在命令行利用hadoop key创建一个key,keytool来生成另一个key,Ranger Admin UI实质上只是把hadoop key -create的操作接口放到了前端。这里hadoop key create到底生成的是哪一个key?我在之前的文本中写生成了EZ key,其实并不见得如此。因为通过Ranger KMS(Apache对hadoop kms的封装,hadoop kms将密钥存储在文件中,Ranger KMS将密钥存储在安全数据库中,且提供可视化界面)只进行了一次生成key的操作。假设我们在UI生成的是EZ key,则意味着实际用于加解密数据的DEK是KMS默认生成的,那么如果用户对实际加密和解密的密钥长度与算法有要求,该怎么处理?
看了一些人写的KMS文档,把我搞得有点迷糊,无奈之下只好用Navicat打开PostGres数据库查看数据库中存放的密钥。rangerkms库下有ranger_keystore和ranger_masterkey两张表,其中在keystore中,自己创建的key1赫然在列,而masterkey(EZ key)表中,是一个长度为256的非用户创建的密钥。于是由此推测,UI创建的是DEK。以上推测暂时也不确定,如有人对此部分比较了解,希望能批评指正,谢谢。
参考:
https://blog.csdn.net/qq_35440040/article/details/78780473
http://www.sohu.com/a/159593316_465944
https://blog.csdn.net/qq_28205153/article/details/55798628