HBase Cell Level Encryption Test Plan - cto-bdt-qa/bdt-qa GitHub Wiki

Feature Description

HBase Cell Level Encryption is a feature that provides a mechanism to encrypt/decrypt HBase Cell. Also, it provides mechanisms to protect users' secrets such as keys. Please note that the feature is mainly implemented at client side. So, it should be able to co-work with 'HBase Transparent Encryption' perfectly. Besides, the cell data should be encrypted/decrypted at the client side. 

To users, the feature only provides API. Inserting/Searching data are not transparent to end users, they should use specific APIs.


Feature Limitations

  • Key store is the only key provider for the feature.
  • Key store is unprotected by any extra mechanisms.
  • Only AES is supported.


Prerequisites

Before using the feature, we should provide HBase with some extra configurations.


Master Key Related Configurations

Encryption keys are the secret used to encrypt users' data. Keys are stored in JKS/JCEKS.


Configure Key Provider

Key provider is a mechanism to provide master key. Currently, all the master keys are stored in JKS or JCEKS.

<property> <name>hbase.client.crypto.keyprovider</name> <value>org.apache.hadoop.io.crypto.KeyStoreKeyProvider</value></property>


Specify Key Store Related Configurations

We need to provide HBase with JKS location, key store type and key store password.

<property> <name>hbase.client.crypto.keyprovider.parameters</name> <value><![CDATA[keyStoreUrl=file:///path/to/hbase/client/conf/hbase.jks&keyStoreType=JCEKS&password=password]]></value></property>

Note that,  XML characters in the value should be escaped, so that the string value can be used as simple text in hbase-site.xml:

  • & -> &amp;

e.g. keyStoreUrl=file:///tmp/hbase_cell.keystore&amp;keyStoreType=JCEKS&amp;password=123456


Specify User-Table-Key Mappings

We should define a statute to tell HBase how to use keys explicitly. The master key is a table-level key. That means each HBase user can specify a master key for a table. The master key should be used by the user who specified key only. 

<property> <name>hbase.crypto.user.key.mapping</name> <value>%t-%u</value></property>

%t represents table name and %u means user name. E.g. According to the above statute, if user A wants to specify his/her master key for table B. The key alias must be B-A.


How to Generate Key Store & Keys

You can use Java key store tool to generate your keystore.

E.g. Create a JCEKS whose password is 123456 and  import a key named B-A to the keystore.

keytool -keystore /path/to/hbase/client/conf/keystore.jks \ -storetype jceks -storepass 123456 \ -genseckey -keyalg AES -keysize 256 \ -alias B-A


Test Scenarios

Construct EncryptedHTable

EncryptedHTable is the user programming interface just like HTable. It provides extra mechenism for encryption. There are 4 approaches to instantiate it.

Instantiate EncryptedHTable with Table name and Configuration

Approach 1

EncryptedHTable htable = new EncryptedHTable(TestContext.HBASE_CONF, Bytes.toBytes(TEST_TBL_1));


Approach 2

EncryptedHTable htable = new EncryptedHTable(TestContext.HBASE_CONF, Bytes.toBytes(TEST_TBL_1), POOL);


Instantiate EncryptedHTable with a Thread Pool

Create a simple thread pool first, then, instantiate EncryptedHTable

private static final ExecutorService POOL = Executors.newCachedThreadPool();


Approach 1

EncryptedHTable htable = new EncryptedHTable(TestContext.HBASE_CONF, Bytes.toBytes("tbl_1"), POOL);


Approach 2

HConnection hConn = HConnectionManager.createConnection(TestContext.HBASE_CONF);EncryptedHTable htable = new EncryptedHTable(Bytes.toBytes("tbl_1"), hConn, POOL);


EncryptedHTableFactory

The feature provides a factory to instantiate and release EncryptedHTables.

Instaniate EncryptedHTable

EncryptedHTableFactory factory = new EncryptedHTableFactory();HTableInterface htable = factory.createHTableInterface(TestContext.HBASE_CONF, Bytes.toByte("tbl_1"));


Release EncryptedHTable

factory.releaseHTableInterface(Bytes.toByte("tbl_1"));


DML

Write encrypted data

  • Write single record:

Write normal data

final Configuration conf = HBaseConfiguration.create(TestContext.HBASE_CONF);final byte[] data = Bytes.toBytes("value");EncryptedHTable htable = new EncryptedHTable(conf, TEST_TBL_1);final byte[] rowKey = Bytes.toBytes(UUID.randomUUID().toString());htable.put(new Put(rowKey).add(TEST_TBL_1_CF1, TEST_TBL_1_QUALIFIER1, data));htable.close(); 


Write data twice

the previous data will be overwritten

final Configuration conf = HBaseConfiguration.create(TestContext.HBASE_CONF);final byte[] data = Bytes.toBytes("value");final byte[] data2 = Bytes.toBytes("value2");EncryptedHTable htable = new EncryptedHTable(conf, TEST_TBL_1);final byte[] rowKey = Bytes.toBytes(UUID.randomUUID().toString());htable.put(new Put(rowKey).add(TEST_TBL_1_CF1, TEST_TBL_1_QUALIFIER1, data));htable.put(new Put(rowKey).add(TEST_TBL_1_CF1, TEST_TBL_1_QUALIFIER1, data2));htable.close();


Write big data

Configuration conf = HBaseConfiguration.create(TestContext.HBASE_CONF);final byte[] data = Bytes.toBytes("qwertyuiopasdfghjklzxcvbnm1234567890qwertyuiop[]asdfgh"+ "jkl;'zxcvbnm,.1234567890-=qwertyuiopasdfghjklzxcvbnm1234567890qwertyuiop[]asdfgh"+ "jkl;'zxcvbnm,.1234567890-=qwertyuiopasdfghjklzxcvbnm1234567890qwertyuiop[]asdfgh"+ "jkl;'zxcvbnm,.1234567890-=qwertyuiopasdfghjklzxcvbnm1234567890qwertyuiop[]asdfgh"+ "jkl;'zxcvbnm,.1234567890-=qwertyuiopasdfghjklzxcvbnm1234567890qwertyuiop[]asdfgh"+ "jkl;'zxcvbnm,.1234567890-=qwertyuiopasdfghjklzxcvbnm1234567890qwertyuiop[]asdfgh"+ "jkl;'zxcvbnm,.1234567890-=" + 23454801);htable = new EncryptedHTable(conf, TEST_TBL_1);byte[] rowId = Bytes.toBytes(UUID.randomUUID().toString());htable.put(new Put(rowId).add(TEST_TBL_1_CF1, TEST_TBL_1_QUALIFIER1, data));


Write empty data

will get empty data when get the value

final Configuration conf = HBaseConfiguration.create(TestContext.HBASE_CONF);final byte[] data = Bytes.toBytes("");EncryptedHTable htable = new EncryptedHTable(conf, TEST_TBL_1);final byte[] rowKey = Bytes.toBytes(UUID.randomUUID().toString());htable.put(new Put(rowKey).add(TEST_TBL_1_CF1, TEST_TBL_1_QUALIFIER1, data));htable.close(); 


Write null data

will get null when get the value

final Configuration conf = HBaseConfiguration.create(TestContext.HBASE_CONF);final byte[] data = null;EncryptedHTable htable = new EncryptedHTable(conf, TEST_TBL_1);final byte[] rowKey = Bytes.toBytes(UUID.randomUUID().toString());htable.put(new Put(rowKey).add(TEST_TBL_1_CF1, TEST_TBL_1_QUALIFIER1, data));htable.close();


  • Write multiple records:

final Configuration conf = HBaseConfiguration.create(TestContext.HBASE_CONF);EncryptedHTable htable = new EncryptedHTable(conf, TEST_TBL_1);Puts puts = HBaseUtils.generatePut(10, TEST_TBL_1_CF2, TEST_TBL_1_QUALIFIER1);htable.put(puts.puts); 

  • Check and write:

Atomically checks if a row/family/qualifier value matches the expected value. If it does, it adds the put.  If the passed value is null, the check is for the lack of column.

Check is passed and write a new data

Configuration conf = HBaseConfiguration.create(TestContext.HBASE_CONF);EncryptedHTable htable = new EncryptedHTable(conf, TEST_TBL_1);final byte[] data = Bytes.toBytes("value");final byte[] data2 = Bytes.toBytes("value2");htable.addFamily(TEST_TBL_1_CF2);byte[] rowId = Bytes.toBytes(UUID.randomUUID().toString());htable.put(new Put(rowId).add(TEST_TBL_1_CF1,TEST_TBL_1_QUALIFIER1, data));if (!htable.checkAndPut(rowId, TEST_TBL_1_CF1, TEST_TBL_1_QUALIFIER1, data,new Put(rowId).add(TEST_TBL_1_CF1, TEST_TBL_1_QUALIFIER1, data2))) {throw new RuntimeException("Check failed!");}

Check is not passed and won't write a new data

Configuration conf = HBaseConfiguration.create(TestContext.HBASE_CONF);EncryptedHTable htable = new EncryptedHTable(conf, TEST_TBL_1);final byte[] data = Bytes.toBytes("value");final byte[] data2 = Bytes.toBytes("value2");htable.addFamily(TEST_TBL_1_CF2);byte[] rowId = Bytes.toBytes(UUID.randomUUID().toString());htable.put(new Put(rowId).add(TEST_TBL_1_CF1,TEST_TBL_1_QUALIFIER1, data));if (htable.checkAndPut(rowId, TEST_TBL_1_CF1, TEST_TBL_1_QUALIFIER1, data2, new Put(rowId).add(TEST_TBL_1_CF1, TEST_TBL_1_QUALIFIER1, data2))) {throw new RuntimeException("Check failed!");} 

Check will also be failed if there's no data

Configuration conf = HBaseConfiguration.create(TestContext.HBASE_CONF);final byte[] data = Bytes.toBytes("value");final byte[] data2 = Bytes.toBytes("value2");htable = new EncryptedHTable(conf, TEST_TBL_1);htable.addFamily(TEST_TBL_1_CF2);byte[] rowId = Bytes.toBytes(UUID.randomUUID().toString());if (htable.checkAndPut(rowId, TEST_TBL_1_CF1, TEST_TBL_1_QUALIFIER1, data, new Put(rowId).add(TEST_TBL_1_CF1, TEST_TBL_1_QUALIFIER1, data2))) {throw new RuntimeException("Check failed!");}

  • Write by mutateRow:

Performs multiple mutations atomically on a single row.

Configuration conf = HBaseConfiguration.create(TestContext.HBASE_CONF);EncryptedHTable htable = new EncryptedHTable(conf, TEST_TBL_1);byte[] rowId = Bytes.toBytes(UUID.randomUUID().toString());RowMutations rmadd = new RowMutations(rowId);rmadd.add(new Put(rowId).add(TEST_TBL_1_CF1, TEST_TBL_1_QUALIFIER1, data));rmadd.add(new Put(rowId).add(TEST_TBL_1_CF1, TEST_TBL_1_QUALIFIER2, data));htable.mutateRow(rmadd);

Edit encrypted data:

  • Increase the value

Increments one or more columns within a single row.  The amount to increment the cell can be either positive or negative.  If overflow the maximun value, it will cycle to the minimun value(example: 9223372036854775807 + 1 = -9223372036854775808).

Increment one or more columns within a single row

Configuration conf = HBaseConfiguration.create(TestContext.HBASE_CONF);EncryptedHTable htable = new EncryptedHTable(conf, TEST_TBL_1);final byte[] data = Bytes.toBytes(123L);final byte[] result = Bytes.toBytes(124L);htable.addFamily(TEST_TBL_1_CF2);byte[] rowId = Bytes.toBytes(UUID.randomUUID().toString());htable.put(new Put(rowId).add(TEST_TBL_1_CF1,TEST_TBL_1_QUALIFIER1, data));htable.increment(new Increment(rowId).addColumn(TEST_TBL_1_CF1, TEST_TBL_1_QUALIFIER1,1));


Increment a column value

Configuration conf = HBaseConfiguration.create(TestContext.HBASE_CONF);EncryptedHTable htable = new EncryptedHTable(conf, TEST_TBL_1);final byte[] data = Bytes.toBytes(123L);final byte[] result = Bytes.toBytes(124L);htable.addFamily(TEST_TBL_1_CF2);byte[] rowId = Bytes.toBytes(UUID.randomUUID().toString());htable.put(new Put(rowId).add(TEST_TBL_1_CF1,TEST_TBL_1_QUALIFIER1, data));htable.incrementColumnValue(rowId, TEST_TBL_1_CF1, TEST_TBL_1_QUALIFIER1, 1); 


Increment a negative amount

Configuration conf = HBaseConfiguration.create(TestContext.HBASE_CONF);final byte[] data = Bytes.toBytes(123L);final byte[] result = Bytes.toBytes(-1L);htable = new EncryptedHTable(conf, TEST_TBL_1);htable.addFamily(TEST_TBL_1_CF2);byte[] rowId = Bytes.toBytes(UUID.randomUUID().toString());htable.put(new Put(rowId).add(TEST_TBL_1_CF1, TEST_TBL_1_QUALIFIER1, data));htable.incrementColumnValue(rowId, TEST_TBL_1_CF1, TEST_TBL_1_QUALIFIER1, -124);


Overflow when increment

Configuration conf = HBaseConfiguration.create(TestContext.HBASE_CONF);final byte[] data = Bytes.toBytes(9223372036854775807L);final byte[] result = Bytes.toBytes(-9223372036854775808L);htable = new EncryptedHTable(conf, TEST_TBL_1);htable.addFamily(TEST_TBL_1_CF2);byte[] rowId = Bytes.toBytes(UUID.randomUUID().toString());htable.put(new Put(rowId).add(TEST_TBL_1_CF1, TEST_TBL_1_QUALIFIER1, data));htable.incrementColumnValue(rowId, TEST_TBL_1_CF1, TEST_TBL_1_QUALIFIER1, 1);


Increment a column value and write logs

Configuration conf = HBaseConfiguration.create(TestContext.HBASE_CONF);EncryptedHTable htable = new EncryptedHTable(conf, TEST_TBL_1);final byte[] data = Bytes.toBytes(123L);final byte[] result = Bytes.toBytes(124L);htable.addFamily(TEST_TBL_1_CF2);byte[] rowId = Bytes.toBytes(UUID.randomUUID().toString());htable.put(new Put(rowId).add(TEST_TBL_1_CF1,TEST_TBL_1_QUALIFIER1, data));htable.incrementColumnValue(rowId, TEST_TBL_1_CF1, TEST_TBL_1_QUALIFIER1, 1, true);

  • Append the string

Appends values to one or more columns within a single row.

Configuration conf = HBaseConfiguration.create(TestContext.HBASE_CONF);EncryptedHTable htable = new EncryptedHTable(conf, TEST_TBL_1);final byte[] data = Bytes.toBytes("a");final byte[] data2 = Bytes.toBytes("b");htable = new EncryptedHTable(conf, TEST_TBL_1);htable.addFamily(TEST_TBL_1_CF2);byte[] rowId = Bytes.toBytes(UUID.randomUUID().toString());htable.put(new Put(rowId).add(TEST_TBL_1_CF1,TEST_TBL_1_QUALIFIER1, data));htable.append(new Append(rowId).add(TEST_TBL_1_CF1,TEST_TBL_1_QUALIFIER1, data2)); 

If append null, nothing will be done

Configuration conf = HBaseConfiguration.create(TestContext.HBASE_CONF);EncryptedHTable htable = new EncryptedHTable(conf, TEST_TBL_1);final byte[] data = Bytes.toBytes("a");final byte[] data2 = null;htable = new EncryptedHTable(conf, TEST_TBL_1);htable.addFamily(TEST_TBL_1_CF2);byte[] rowId = Bytes.toBytes(UUID.randomUUID().toString());htable.put(new Put(rowId).add(TEST_TBL_1_CF1,TEST_TBL_1_QUALIFIER1, data));htable.append(new Append(rowId).add(TEST_TBL_1_CF1,TEST_TBL_1_QUALIFIER1, data2));

Read encrypted data

  • Read data by Get:

byte[] rs = htable.get(new Get(rowKey)).getValue(TEST_TBL_1_CF1,TEST_TBL_1_QUALIFIER1);

Scan encrypted data

  • Scan by given family and column:

Configuration conf = HBaseConfiguration.create(TestContext.HBASE_CONF);EncryptedHTable htable = new EncryptedHTable(conf, TEST_TBL_1);ResultScanner scanner = htable.getScanner(TEST_TBL_1_CF2,TEST_TBL_1_QUALIFIER1); 

  • Scan by given family:

Configuration conf = HBaseConfiguration.create(TestContext.HBASE_CONF);EncryptedHTable htable = new EncryptedHTable(conf, TEST_TBL_1);ResultScanner scanner = htable.getScanner(TEST_TBL_1_CF2);

  • Scan by specified object:

Configuration conf = HBaseConfiguration.create(TestContext.HBASE_CONF);EncryptedHTable htable = new EncryptedHTable(conf, TEST_TBL_1);Scan scan = new Scan();scan.setMaxVersions(1);scan.addColumn(TEST_TBL_1_CF2, TEST_TBL_1_QUALIFIER1);ResultScanner scanner = htable.getScanner(scan);Iterator<Result> it = scanner.iterator();while (it.hasNext()) {Result rs = it.next();if (!IDS.contains(Bytes.toString(rs.getRow()))) {assertTrue("Test result is out of the expected data.",false);}else {KeyValue[] kvs = rs.raw();for (KeyValue kv : kvs) {if (Bytes.equals(Bytes.toBytes("value"), kv.getValue())) {assertTrue("Unexpected test result.", false);}}}} 

nonexistent data won't be scanned

Configuration conf = HBaseConfiguration.create(TestContext.HBASE_CONF);EncryptedHTable htable = new EncryptedHTable(conf, TEST_TBL_1);Scan scan = new Scan();scan.setMaxVersions(1);scan.addColumn(TEST_TBL_1_CF2, TEST_TBL_1_QUALIFIER1);ResultScanner scanner = htable.getScanner(scan);Iterator<Result> it = scanner.iterator();while (it.hasNext()) {Result rs = it.next();if (!IDS.contains(Bytes.toString(rs.getRow()))) {assertTrue("Test result is out of the expected data.",false);}else {KeyValue[] kvs = rs.raw();for (KeyValue kv : kvs) {if (Bytes.equals(Bytes.toBytes("value123"), kv.getValue())) {assertTrue("Unexpected test result.", false);}}}}

  • Scan and return row:

Configuration conf = HBaseConfiguration.create(TestContext.HBASE_CONF);EncryptedHTable htable = new EncryptedHTable(conf, TEST_TBL_1);Result rs = htable.getRowOrBefore(Bytes.toBytes(rowId),TEST_TBL_1_CF2);if (!Bytes.equals(Bytes.toBytes("value"),rs.getValue(TEST_TBL_1_CF2, TEST_TBL_1_QUALIFIER1))){throw new RuntimeException("Data is fetched & decrypted failed!");} 

nonexistent data won't be scanned

Configuration conf = HBaseConfiguration.create(TestContext.HBASE_CONF);EncryptedHTable htable = new EncryptedHTable(conf, TEST_TBL_1);Result rs = htable.getRowOrBefore(Bytes.toBytes(rowId),TEST_TBL_1_CF2);if (!Bytes.equals(Bytes.toBytes("value123"),rs.getValue(TEST_TBL_1_CF2, TEST_TBL_1_QUALIFIER1))){throw new RuntimeException("Data is fetched & decrypted failed!");}

Delete encrypted data

  • Check and delete:

Atomically checks if a row/family/qualifier value matches the expected value. If it does, it adds the delete.  If the passed value is null, the check is for the lack of column.

Check is passed and delete the data

Configuration conf = HBaseConfiguration.create(TestContext.HBASE_CONF);EncryptedHTable htable = new EncryptedHTable(conf, TEST_TBL_1);htable.addFamily(TEST_TBL_1_CF2);byte[] rowId = Bytes.toBytes(UUID.randomUUID().toString());htable.put(new Put(rowId).add(TEST_TBL_1_CF1,TEST_TBL_1_QUALIFIER1, data));if (!htable.checkAndDelete(rowId, TEST_TBL_1_CF1, TEST_TBL_1_QUALIFIER1, data,new Delete(rowId).deleteColumn(TEST_TBL_1_CF1, TEST_TBL_1_QUALIFIER1))) {throw new RuntimeException("Check failed!");} 


Check is not passed and won't delete the data

Configuration conf = HBaseConfiguration.create(TestContext.HBASE_CONF);final byte[] data = Bytes.toBytes("value");final byte[] data2 = Bytes.toBytes("value2");htable = new EncryptedHTable(conf, TEST_TBL_1);htable.addFamily(TEST_TBL_1_CF2);byte[] rowId = Bytes.toBytes(UUID.randomUUID().toString());htable.put(new Put(rowId).add(TEST_TBL_1_CF1, TEST_TBL_1_QUALIFIER1, data));if (htable.checkAndDelete(rowId, TEST_TBL_1_CF1, TEST_TBL_1_QUALIFIER1, data2,new Delete(rowId).deleteColumn(TEST_TBL_1_CF1, TEST_TBL_1_QUALIFIER1))) {throw new RuntimeException("Check failed!");}

  • Delete by mutateRow:

Performs multiple mutations atomically on a single row.

Configuration conf = HBaseConfiguration.create(TestContext.HBASE_CONF);EncryptedHTable htable = new EncryptedHTable(conf, TEST_TBL_1);byte[] rowId = Bytes.toBytes(UUID.randomUUID().toString());RowMutations rmdelete = new RowMutations(rowId);rmdelete.add(new Delete(rowId).deleteColumn(TEST_TBL_1_CF1, TEST_TBL_1_QUALIFIER1));rmdelete.add(new Delete(rowId).deleteColumn(TEST_TBL_1_CF1, TEST_TBL_1_QUALIFIER2));htable.mutateRow(rmdelete); 

Batch operate 

Method that does a batch call on Deletes, Gets, Puts, Increments, Appends and RowMutations.

Configuration conf = HBaseConfiguration.create(TestContext.HBASE_CONF);final byte[] data1 = Bytes.toBytes("a");final byte[] data2 = Bytes.toBytes("b");final byte[] data3 = Bytes.toBytes(2L);final byte[] data4 = Bytes.toBytes(3L);final byte[] data = Bytes.toBytes("ab");htable = new EncryptedHTable(conf, TEST_TBL_1);byte[] rowId = Bytes.toBytes(UUID.randomUUID().toString());byte[] rowId2 = Bytes.toBytes(UUID.randomUUID().toString());byte[] rowId3 = Bytes.toBytes(UUID.randomUUID().toString());htable.addFamily(TEST_TBL_1_CF2);htable.put(new Put(rowId).add(TEST_TBL_1_CF1, TEST_TBL_1_QUALIFIER1, data1));htable.put(new Put(rowId3).add(TEST_TBL_1_CF1, TEST_TBL_1_QUALIFIER1, data3));List<Row> action = new ArrayList<Row>();Put put = new Put(rowId2).add(TEST_TBL_1_CF1, TEST_TBL_1_QUALIFIER1, data1);action.add(put);Append append = new Append(rowId).add(TEST_TBL_1_CF1, TEST_TBL_1_QUALIFIER1, data2);action.add(append);Increment increment = new Increment(rowId3).addColumn( TEST_TBL_1_CF1, TEST_TBL_1_QUALIFIER1, 1);action.add(increment);Get get = new Get(rowId).addColumn(TEST_TBL_1_CF1, TEST_TBL_1_QUALIFIER1);action.add(get);htable.batch(action);

Edit Column Family

Add Column Family

Configuration conf = HBaseConfiguration.create(TestContext.HBASE_CONF);EncryptedHTable htable = new EncryptedHTable(conf, TEST_TBL_1);htable.addFamily(Bytes.toBytes("cf1"));Collection<byte[]> family = htable.getFamilySet(); 

Add  a family twice

When add a family already in the familyset, action is allowed but nothing will be done.

Configuration conf = HBaseConfiguration.create(TestContext.HBASE_CONF);EncryptedHTable htable = new EncryptedHTable(conf, TEST_TBL_1);htable.addFamily(Bytes.toBytes("cf1"));htable.addFamily(Bytes.toBytes("cf1"));Collection<byte[]> family = htable.getFamilySet();

Remove Column Family

Configuration conf = HBaseConfiguration.create(TestContext.HBASE_CONF);EncryptedHTable htable = new EncryptedHTable(conf, TEST_TBL_1);htable.removeFamily(Bytes.toBytes("cf1"));Collection<byte[]> family = htable.getFamilySet(); 

Remove  a family twice

When remove a family not in the familyset, action is allowed but nothing will be done.

Configuration conf = HBaseConfiguration.create(TestContext.HBASE_CONF);EncryptedHTable htable = new EncryptedHTable(conf, TEST_TBL_1);htable.removeFamily(Bytes.toBytes("cf1"));htable.removeFamily(Bytes.toBytes("cf1"));Collection<byte[]> family = htable.getFamilySet();

Set Column Family

Configuration conf = HBaseConfiguration.create(TestContext.HBASE_CONF);EncryptedHTable htable = new EncryptedHTable(conf, TEST_TBL_1);List<byte[]> family = new ArrayList<byte[]>();family.add(TEST_TBL_1_CF1);family.add(TEST_TBL_1_CF2);htable.setFamilySet(family); 

Get Column Family

family = htable.getFamilySet();  


Test Driver Guide

Prerequisites

Please configure hbase client crypto related configurations before running test cases. The keystore named hbase-cell.keystore has been put in resource dir of the test driver. The password of keystore is 123456 and store type is JCEKS.


Download

svn co https://sh-ssvn.sh.intel.com/ssg_repos/svn_hadoop/hadoop/hadoop/QA/Basic_feature_test/trunk/hbase-encryption-cell/


Execution

Please execute the test driver with user root.

ant runner

⚠️ **GitHub.com Fallback** ⚠️