You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@hbase.apache.org by ap...@apache.org on 2015/02/25 03:58:29 UTC

[4/4] hbase git commit: HBASE-13048 Use hbase.crypto.wal.algorithm in SecureProtobufLogReader while decrypting the data

HBASE-13048 Use hbase.crypto.wal.algorithm in SecureProtobufLogReader while decrypting the data

Signed-off-by: Andrew Purtell <ap...@apache.org>


Project: http://git-wip-us.apache.org/repos/asf/hbase/repo
Commit: http://git-wip-us.apache.org/repos/asf/hbase/commit/3727bd3c
Tree: http://git-wip-us.apache.org/repos/asf/hbase/tree/3727bd3c
Diff: http://git-wip-us.apache.org/repos/asf/hbase/diff/3727bd3c

Branch: refs/heads/0.98
Commit: 3727bd3caef141b211facbf3d6a5115610416955
Parents: f4fa876
Author: Ashish Singhi <as...@huawei.com>
Authored: Tue Feb 24 11:20:09 2015 +0530
Committer: Andrew Purtell <ap...@apache.org>
Committed: Tue Feb 24 18:18:44 2015 -0800

----------------------------------------------------------------------
 .../hadoop/hbase/security/EncryptionUtil.java   | 27 ++++++++++++
 .../hbase/security/TestEncryptionUtil.java      | 45 ++++++++++++++++++++
 .../wal/SecureProtobufLogReader.java            |  6 +--
 3 files changed, 75 insertions(+), 3 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/hbase/blob/3727bd3c/hbase-client/src/main/java/org/apache/hadoop/hbase/security/EncryptionUtil.java
----------------------------------------------------------------------
diff --git a/hbase-client/src/main/java/org/apache/hadoop/hbase/security/EncryptionUtil.java b/hbase-client/src/main/java/org/apache/hadoop/hbase/security/EncryptionUtil.java
index 485388e..2cd2a56 100644
--- a/hbase-client/src/main/java/org/apache/hadoop/hbase/security/EncryptionUtil.java
+++ b/hbase-client/src/main/java/org/apache/hadoop/hbase/security/EncryptionUtil.java
@@ -119,6 +119,11 @@ public class EncryptionUtil {
     if (cipher == null) {
       throw new RuntimeException("Cipher '" + algorithm + "' not available");
     }
+    return getUnwrapKey(conf, subject, wrappedKey, cipher);
+  }
+
+  private static Key getUnwrapKey(Configuration conf, String subject,
+      EncryptionProtos.WrappedKey wrappedKey, Cipher cipher) throws IOException, KeyException {
     ByteArrayOutputStream out = new ByteArrayOutputStream();
     byte[] iv = wrappedKey.hasIv() ? wrappedKey.getIv().toByteArray() : null;
     Encryption.decryptWithSubjectKey(out, wrappedKey.getData().newInput(),
@@ -132,4 +137,26 @@ public class EncryptionUtil {
     return new SecretKeySpec(keyBytes, wrappedKey.getAlgorithm());
   }
 
+  /**
+   * Unwrap a wal key by decrypting it with the secret key of the given subject. The configuration
+   * must be set up correctly for key alias resolution.
+   * @param conf configuration
+   * @param subject subject key alias
+   * @param value the encrypted key bytes
+   * @return the raw key bytes
+   * @throws IOException if key is not found for the subject, or if some I/O error occurs
+   * @throws KeyException if fail to unwrap the key
+   */
+  public static Key unwrapWALKey(Configuration conf, String subject, byte[] value)
+      throws IOException, KeyException {
+    EncryptionProtos.WrappedKey wrappedKey =
+        EncryptionProtos.WrappedKey.PARSER.parseDelimitedFrom(new ByteArrayInputStream(value));
+    String algorithm = conf.get(HConstants.CRYPTO_WAL_ALGORITHM_CONF_KEY, HConstants.CIPHER_AES);
+    Cipher cipher = Encryption.getCipher(conf, algorithm);
+    if (cipher == null) {
+      throw new RuntimeException("Cipher '" + algorithm + "' not available");
+    }
+    return getUnwrapKey(conf, subject, wrappedKey, cipher);
+  }
+
 }

http://git-wip-us.apache.org/repos/asf/hbase/blob/3727bd3c/hbase-client/src/test/java/org/apache/hadoop/hbase/security/TestEncryptionUtil.java
----------------------------------------------------------------------
diff --git a/hbase-client/src/test/java/org/apache/hadoop/hbase/security/TestEncryptionUtil.java b/hbase-client/src/test/java/org/apache/hadoop/hbase/security/TestEncryptionUtil.java
index 7aea5d9..5d23b1d 100644
--- a/hbase-client/src/test/java/org/apache/hadoop/hbase/security/TestEncryptionUtil.java
+++ b/hbase-client/src/test/java/org/apache/hadoop/hbase/security/TestEncryptionUtil.java
@@ -73,4 +73,49 @@ public class TestEncryptionUtil {
     }
   }
 
+  @Test
+  public void testWALKeyWrapping() throws Exception {
+    // set up the key provider for testing to resolve a key for our test subject
+    Configuration conf = new Configuration(); // we don't need HBaseConfiguration for this
+    conf.set(HConstants.CRYPTO_KEYPROVIDER_CONF_KEY, KeyProviderForTesting.class.getName());
+
+    // generate a test key
+    byte[] keyBytes = new byte[AES.KEY_LENGTH];
+    new SecureRandom().nextBytes(keyBytes);
+    String algorithm = conf.get(HConstants.CRYPTO_WAL_ALGORITHM_CONF_KEY, HConstants.CIPHER_AES);
+    Key key = new SecretKeySpec(keyBytes, algorithm);
+
+    // wrap the test key
+    byte[] wrappedKeyBytes = EncryptionUtil.wrapKey(conf, "hbase", key);
+    assertNotNull(wrappedKeyBytes);
+
+    // unwrap
+    Key unwrappedKey = EncryptionUtil.unwrapWALKey(conf, "hbase", wrappedKeyBytes);
+    assertNotNull(unwrappedKey);
+    // only secretkeyspec supported for now
+    assertTrue(unwrappedKey instanceof SecretKeySpec);
+    // did we get back what we wrapped?
+    assertTrue("Unwrapped key bytes do not match original",
+      Bytes.equals(keyBytes, unwrappedKey.getEncoded()));
+  }
+
+  @Test(expected = KeyException.class)
+  public void testWALKeyWrappingWithIncorrectKey() throws Exception {
+    // set up the key provider for testing to resolve a key for our test subject
+    Configuration conf = new Configuration(); // we don't need HBaseConfiguration for this
+    conf.set(HConstants.CRYPTO_KEYPROVIDER_CONF_KEY, KeyProviderForTesting.class.getName());
+
+    // generate a test key
+    byte[] keyBytes = new byte[AES.KEY_LENGTH];
+    new SecureRandom().nextBytes(keyBytes);
+    String algorithm = conf.get(HConstants.CRYPTO_WAL_ALGORITHM_CONF_KEY, HConstants.CIPHER_AES);
+    Key key = new SecretKeySpec(keyBytes, algorithm);
+
+    // wrap the test key
+    byte[] wrappedKeyBytes = EncryptionUtil.wrapKey(conf, "hbase", key);
+    assertNotNull(wrappedKeyBytes);
+
+    // unwrap with an incorrect key
+    EncryptionUtil.unwrapWALKey(conf, "other", wrappedKeyBytes);
+  }
 }

http://git-wip-us.apache.org/repos/asf/hbase/blob/3727bd3c/hbase-server/src/main/java/org/apache/hadoop/hbase/regionserver/wal/SecureProtobufLogReader.java
----------------------------------------------------------------------
diff --git a/hbase-server/src/main/java/org/apache/hadoop/hbase/regionserver/wal/SecureProtobufLogReader.java b/hbase-server/src/main/java/org/apache/hadoop/hbase/regionserver/wal/SecureProtobufLogReader.java
index 041dfe2..d175741 100644
--- a/hbase-server/src/main/java/org/apache/hadoop/hbase/regionserver/wal/SecureProtobufLogReader.java
+++ b/hbase-server/src/main/java/org/apache/hadoop/hbase/regionserver/wal/SecureProtobufLogReader.java
@@ -78,7 +78,7 @@ public class SecureProtobufLogReader extends ProtobufLogReader {
       // First try the WAL key, if one is configured
       if (walKeyName != null) {
         try {
-          key = EncryptionUtil.unwrapKey(conf, walKeyName, keyBytes);
+          key = EncryptionUtil.unwrapWALKey(conf, walKeyName, keyBytes);
         } catch (KeyException e) {
           if (LOG.isDebugEnabled()) {
             LOG.debug("Unable to unwrap key with WAL key '" + walKeyName + "'");
@@ -91,7 +91,7 @@ public class SecureProtobufLogReader extends ProtobufLogReader {
           User.getCurrent().getShortName());
         try {
           // Then, try the cluster master key
-          key = EncryptionUtil.unwrapKey(conf, masterKeyName, keyBytes);
+          key = EncryptionUtil.unwrapWALKey(conf, masterKeyName, keyBytes);
         } catch (KeyException e) {
           // If the current master key fails to unwrap, try the alternate, if
           // one is configured
@@ -102,7 +102,7 @@ public class SecureProtobufLogReader extends ProtobufLogReader {
             conf.get(HConstants.CRYPTO_MASTERKEY_ALTERNATE_NAME_CONF_KEY);
           if (alternateKeyName != null) {
             try {
-              key = EncryptionUtil.unwrapKey(conf, alternateKeyName, keyBytes);
+              key = EncryptionUtil.unwrapWALKey(conf, alternateKeyName, keyBytes);
             } catch (KeyException ex) {
               throw new IOException(ex);
             }