
# 加密HFile和WAL内容
缺省情况下，HBase中的HFile和WAL（Write ahead log）内容是不加密的。如果用户需要对其进行加密，可通过该章节操作进行配置。
![](https://support.huaweicloud.com/usermanual-mrs/public_sys-resources/warning_3.0-zh-cn.png)
设置HFile和WAL为SM4（也称为SMS4）加密或AES加密方式对系统的影响较大，一旦操作失误会导致数据丢失，不推荐使用此功能。
#### 约束与限制
- 使用BulkLoad批量导入的数据不支持加密。
- 本章节内容仅适用于MRS 3.x及之后版本。
 
 #### 加密HFile和WAL内容
1. 在任一安装HBase服务节点，使用**omm** 用户执行如下命令创建密钥。
   
   **sh ${BIGDATA_HOME}/FusionInsight_HD_**8.1.0.1**** **/install/FusionInsight-HBase-2.2.3/hbase/bin/hbase-encrypt.sh** *\<path\>/hbase.jks* *\<type\>* *\<length\> \<alias\>*
   - */\<path\>/hbase.jks*表示生成的jks文件存储路径。
   
   - *\<type\>*表示加密的类型，支持SM4（也称为SMS4）和AES。
   
   - *\<length\>*表示密钥的长度，SM4（也称为SMS4）支持16位长度，AES支持128位长度。
   
   - *\<alias\>*为密钥文件的别名，第一次生成时请使用缺省值"omm"。
   
   
   例如，生成SM4（也称为SMS4）加密的密钥执行：
   **sh ${BIGDATA_HOME}/**FusionInsight_HD_**** **8.1.0.1** ****/install**/FusionInsight-HBase-2.2.3/hbase/bin/hbase-encrypt.sh /home/hbase/conf/hbase.jks SMS4 16 omm**
   生成AES加密的密钥执行：
   **sh ${BIGDATA_HOME}/****FusionInsight_HD_****** **8.1.0.1** ******/install****/FusionInsight-HBase-2.2.3/hbase/bin/hbase-encrypt.sh /home/hbase/conf/hbase.jks AES 128 omm**
   - 集群的操作用户需要有*\<path\>/hbase.jks*目录的"rw"权限，且要求目录已存在。
   
   - 运行命令后需要再输入4遍相同的*\<password\>* ，其中[步骤 3]中进行加密的密码与此步骤的密码相同。
   
   
   
   
2. 将生成的密钥文件分发到集群中所有节点的相同目录下，并为**omm** 用户配置该文件的读写权限。
   
   - 请管理员根据企业安全要求，选择安全的操作步骤分发密钥。
   
   - 如果在使用过程中，有节点出现密钥文件丢失的情况，请按照此步骤从其他节点复制到该节点。
   
   
   
   
3. 在Manager界面中，选择"集群 \> 服务 \> HBase \> 配置"，在搜索框中搜索并配置以下参数：
   
   登录集群Manager具体操作，请参考[访问MRS集群Manager](https://support.huaweicloud.com/usermanual-mrs/mrs_01_0128.html)。
   - hbase.crypto.keyprovider.parameters.encryptedtext：设置该参数值为密文密码，格式为：*\<encrypted_password\>* 。
     *\<encrypted_password\>* 填写创建密钥时的密文密码，参数值显示为密文。可使用**omm**用户在安装HBase服务的节点，执行如下命令获取对应加密后的密码：
     **sh ${BIGDATA_HOME}/******FusionInsight_HD_******** **8.1.0.1** ********/install******/FusionInsight-HBase-2.2.3/hbase/bin/hbase-encrypt.sh**
     运行该命令后需要输入\<password\>，与[步骤 1]中手动输入的密码相同。
     
   
   - hbase.crypto.keyprovider.parameters.uri：设置该参数值为密钥路径和名称，格式为：**jceks://** *\<key_Path_Name\>* 。
     *\<key_Path_Name\>*填写密钥的存储路径，例如"/home/hbase/conf/hbase.jks"，则对应参数值为"jceks:///home/hbase/conf/hbase.jks"。
     
   
   - hbase.crypto.key.algorithm：设置该参数值为"SMS4"或"AES"，使HFile的内容采用SM4（也称为SMS4）或AES的方式加密。
   
   - hbase.crypto.wal.algorithm：设置该参数值为"SMS4"或"AES"，使WAL的内容采用SM4（也称为SMS4）或AES的方式加密。
   
   - hbase.regionserver.wal.encryption：将该参数值修改为"true"。
   
   
   
   
4. 单击"保存"保存设置。单击"概览"，在页面右上角选择"更多 \> 重启服务"，输入当前用户密码后单击"确定"，重启HBase服务使其生效。
5. 在创建HBase表时，需要通过设置加密方式开启加密功能，\<type\>表示加密的类型，"d"为加密列族。
   
   - 通过命令行创建表时，直接为列族设置加密方式为SM4（也称为SMS4）或AES。 ***create*** '*\<table name\>* ', {**NAME =\>** *'d'* , **ENCRYPTION =\>*'*** *\<type\>* **'**}
     
   
   - 使用代码创建表时，在代码中添加如下信息设置加密方式为SM4（也称为SMS4）或AES。
     ```
     public void testCreateTable() 
     { 
         String tableName = "user"; 
         Configuration conf = getConfiguration();    
         HTableDescriptor htd = new HTableDescriptor(TableName.valueOf(tableName)); 
          
         HColumnDescriptor hcd = new HColumnDescriptor("d"); 
         //设置加密方式为SM4（也称为SMS4）或AES。 
         hcd.setEncryptionType("<type>"); 
         htd.addFamily(hcd); 
      
         HBaseAdmin admin = null; 
         try 
         { 
             admin = new HBaseAdmin(conf); 
              
             if(!admin.tableExists(tableName)) 
             { 
                 admin.createTable(htd); 
             } 
         } 
         catch (IOException e) 
         { 
             e.printStackTrace(); 
         } 
         finally 
         { 
             if(admin != null) 
             { 
                 try 
                 { 
                     admin.close(); 
                 } 
                 catch (IOException e) 
                 { 
                     e.printStackTrace(); 
                 } 
             } 
         } 
     }
     ```
     
   
   
   
   
6. 可参考[验证加密是否配置成功]验证加密是否配置成功。
7. 如果用户已按照[步骤 1]到[步骤 4]配置了SM4（也称为SMS4）或AES加密，但是在执行[步骤 5]创建表时，未设置对应的加密参数，使得插入的数据未经加密。
   
   此时，您可以执行如下步骤对之前插入的数据进行加密。
   1. 针对表执行**flush** 操作，将内存中的数据导入到HFile中。
      **flush** *'\<table_name\>'*
      
   
   2. 执行以下步骤修改表属性： **disable** *'\<table_name\>'*
      **alter** *'* *\<table_name\>'**,*** **NAME=\>** *'\<column_name\>'**,*** **ENCRYPTION =\>** ***'**\<type\>* **'**
      **enable** *'* *\<table_name\>'*
      
   
   3. 插入一条新的数据，然后再**flush** 表。
      必须要插入一条新的数据，HFile才会生成新的HFile，使得之前插入的未加密数据进行重写加密。
      **put** *'\<table_name\>'* ,***'*id2','f1:c1','value222222222222222222222222222222222'**
      **flush** *'\<table_name\>'*
      
   
   4. 执行如下步骤重写HFile。 **major_compact** '*\<table_name\>'*
      ![](https://support.huaweicloud.com/usermanual-mrs/public_sys-resources/warning_3.0-zh-cn.png)
      执行此步骤时，HBase表是被禁用的，不能对外提供表服务，请谨慎使用。
      
   
   5. 可执行[步骤 6]验证加密是否配置成功。
   
   
   
   
 
 #### 验证加密是否配置成功
仅当所配置的空表允许写入测试数据时可执行该操作。
1. 以客户端安装用户，登录安装客户端的节点。切换到客户端安装目录，例如：/opt/client。
   
   **cd /opt/client**
   
   
2. 执行以下命令配置环境变量。 
   **source bigdata_env**
   
   
3. 如果当前集群已启用Kerberos认证，执行以下命令认证当前用户，当前用户需要具有读写HBase表的权限和HDFS的操作权限： 
   **kinit** *组件业务用户*
   如果当前集群未启用Kerberos认证，则执行以下命令设置Hadoop用户名：
   **export HADOOP_USER_NAME=hbase**
   
   
4. 执行以下命令进入HBase客户端。
   
   **hbase shell**
   执行以下命令插入一条新的数据，然后flush表，生成HFile。
   **put** *'\<table_name\>'* ,***'*id2','** *d* **:c1','value222222222222222222222222222222222'**
   **flush** *'\<table_name\>'*
   - "*\<table_name\>* "为[步骤 5]已配置了SM4（也称为SMS4）或AES加密的表。
   
   - "*d* "为[步骤 5]已配置了SM4（也称为SMS4）或AES加密的列族。
   
   
   
   
5. 执行"Ctrl+C"命令退出HBase客户端。
6. 执行以下命令查看[步骤 4]生成的HFile文件所在目录。
   
   **hdfs dfs -ls**
   文件目录格式为：**/hbase/data/** *\<namespace_name\>* **/** *\<table_name\>* **/** *\<region_name\>* **/** *\<columnfamily_name\>* **/** *\<HFile_name\>*
   创建HBase建表时若未指定表的"*\<namespace_name\>*"则默认为default。
   例如：
   ```
   /hbase/data/default/create_table/dd61b81b1ba1aad6513b9bdcfd8f871c/d/aa6fe387b27443afaba40f5b584c1fa7
   ```
   
   
7. 执行以下命令查看HFile内容： 
   **hbase hfile -f** *\<hfile路径\>* **-p**
   "*\<hfile路径\>* "为[步骤 6]查看到的HFile文件所在目录。
   该命令将报"com.huawei.hadoop.hbase.io.crypto.CryptoRuntimeException"或"java.lang.RuntimeException: Failed to decrypt encrypted text"异常。此时**hbase shell**中仍可正常读取该表数据，即加密配置成功。
   
   
 
#### 修改密钥文件
在[加密HFile和WAL内容]操作中需要生成对应的密钥文件并设置密码，为确保系统安全，在运行一段时间后，用户可修改密钥，使用新的密钥文件对HFile和WAL内容进行加密。
![](https://support.huaweicloud.com/usermanual-mrs/public_sys-resources/warning_3.0-zh-cn.png)
修改密钥文件的操作对系统影响较大，一旦操作失误会导致数据丢失，不推荐使用此功能。
1. 使用**omm** 用户执行如下命令生成新的密钥文件。
   
   **sh ${BIGDATA_HOME}/********FusionInsight_HD_**8.1.0.1************ **********/install********/FusionInsight-HBase-2.2.3/hbase/bin/hbase-encrypt.sh** *\<path\>/hbase.jks* *\<type\> \<length\> \<alias-new\>*
   - *\<path\>/hbase.jks* ：表示生成的hbase.jks文件的存储路径。该路径和文件名称需与[加密HFile和WAL内容]章节生成的密钥文件相同。
   
   - *\<alias-new\>*：表示密钥文件的别名，请使用与旧密钥文件不同的名字。
   
   - *\<type\>*：表示加密的类型，支持SM4（也称为SMS4）或AES。
   
   - *\<length\>*：表示密钥的长度，SM4（也称为SMS4）支持16位长度，AES支持128位长度。
   
   
   例如，生成SM4（也称为SMS4）加密的密钥执行：
   **sh ${BIGDATA_HOME}/** ****FusionInsight_HD_**** **8.1.0.1** ****/install**** **/FusionInsight-HBase-2.2.3/hbase/bin/hbase-encrypt.sh /home/hbase/conf/hbase.jks SMS4 16 omm_new**
   生成AES加密的密钥执行：
   **sh ${BIGDATA_HOME}/****FusionInsight_HD_****** **8.1.0.1** ******/install****/FusionInsight-HBase-2.2.3/hbase/bin/hbase-encrypt.sh /home/hbase/conf/hbase.jks AES 128 omm_new**
   - 集群的操作用户需要有*\<path\>/hbase.jks*目录的"rw"权限，且要求目录已存在。
   
   - 运行命令后需要再输入3遍相同的*\<password\>*，该密码表示密钥文件的密码，请直接使用旧文件的密码，不会产生安全风险。
   
   
   
   
2. 将生成的密钥文件分发到集群中所有节点的相同目录下，并为**omm** 用户配置该文件的读写权限。
   
   请管理员根据企业安全要求，选择安全的操作步骤分发密钥。
   
   
3. 登录MRS集群Manager界面，具体请参见[访问MRS集群Manager](https://support.huaweicloud.com/usermanual-mrs/mrs_01_0128.html)，选择"集群 \> 服务 \> HBase \> 配置"，在搜索框中搜索"hadoop.config.expandor"，新增以下自定义配置参数。
   
   登录集群Manager具体操作，请参考[访问MRS集群Manager](https://support.huaweicloud.com/usermanual-mrs/mrs_01_0128.html)。
   - 新增自定义参数名称为"hbase.crypto.master.key.name"，值为"omm_new"。
   
   - 新增自定义参数名称为"hbase.crypto.master.alternate.key.name"，值为"omm"
   
   
   图1新增自定义参数   
   ![](https://support.huaweicloud.com/usermanual-mrs/zh-cn_image_0000001879420716.png "点击放大")
   
   
4. 单击"保存"保存设置。单击"概览"，在页面右上角选择"更多 \> 重启服务"，输入当前用户密码后单击"确定"，重启HBase服务使其生效。
5. 参考[验证加密是否配置成功]的[步骤 1]\~[步骤 4]登录HBase客户端，并执行**major compact** 命令，生成基于新的加密算法的HFile文件。
   
   **major_compact** *'\<table_name\>'*
   
   
6. 在Manager界面，选择"集群 \> 服务 \> HBase"，单击"HMaster Web UI"右侧的超链接，进入HMaster WebUI界面，单击"Region Servers"页签的"Compactions"即可查看到**major compact** 进度。
   
   ![](https://support.huaweicloud.com/usermanual-mrs/zh-cn_image_0000001879580588.png "点击放大")
   
   
7. 所有的"Compaction Progress"都为100%且"Remaining KVs"都为0时，使用**omm** 用户执行如下命令销毁旧的密钥文件：
   
   **sh ${BIGDATA_HOME}/******FusionInsight_HD_**8.1.0.1********** ********/install******/FusionInsight-HBase-2.2.3/hbase/bin/hbase-encrypt.sh** *\<path\>/hbase.jks \<alias-old\>*
   - *\<path\>/hbase.jks* :表示生成的"hbase.jks"文件的存储路径。该路径和文件名称需与[加密HFile和WAL内容](https://support.huaweicloud.com/usermanual-mrs/admin_guide_000276.html#admin_guide_000276)章节生成的密钥文件相同。
   
   - *\<alias-old\>*：表示要删除的旧密钥文件的别名。
   
   
   例如：
   **sh ${BIGDATA_HOME}/******FusionInsight_HD_******** **8.1.0.1** ********/install******/FusionInsight-HBase-2.2.3/hbase/bin/hbase-encrypt.sh /home/hbase/conf/hbase.jks omm**
   集群的操作用户需要有*\<path\>/hbase.jks*目录的"rw"权限，且要求目录已存在。
   
   
8. 再执行[步骤 2]，重新分发更新后的密钥文件。
9. 从Manager界面中删除[步骤 3]中新增HBase自定义配置项"hbase.crypto.master.alternate.key.name"。
10. 再执行[步骤 4]使配置生效。
 
