You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ranger.apache.org by co...@apache.org on 2017/04/11 14:15:56 UTC
ranger git commit: RANGER-1505 - Remove KeyProtector code in KMS
Repository: ranger
Updated Branches:
refs/heads/master c89b55591 -> 6e512b6ab
RANGER-1505 - Remove KeyProtector code in KMS
Signed-off-by: Colm O hEigeartaigh <co...@apache.org>
Project: http://git-wip-us.apache.org/repos/asf/ranger/repo
Commit: http://git-wip-us.apache.org/repos/asf/ranger/commit/6e512b6a
Tree: http://git-wip-us.apache.org/repos/asf/ranger/tree/6e512b6a
Diff: http://git-wip-us.apache.org/repos/asf/ranger/diff/6e512b6a
Branch: refs/heads/master
Commit: 6e512b6ab5c7d2008ff8e1abd2ad9f1b8b12e169
Parents: c89b555
Author: Colm O hEigeartaigh <co...@apache.org>
Authored: Mon Apr 10 12:23:38 2017 +0100
Committer: Colm O hEigeartaigh <co...@apache.org>
Committed: Tue Apr 11 15:15:48 2017 +0100
----------------------------------------------------------------------
.../hadoop/crypto/key/RangerKeyStore.java | 105 ++++++++++++++-----
1 file changed, 79 insertions(+), 26 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/ranger/blob/6e512b6a/kms/src/main/java/org/apache/hadoop/crypto/key/RangerKeyStore.java
----------------------------------------------------------------------
diff --git a/kms/src/main/java/org/apache/hadoop/crypto/key/RangerKeyStore.java b/kms/src/main/java/org/apache/hadoop/crypto/key/RangerKeyStore.java
index a001c08..c4f7267 100644
--- a/kms/src/main/java/org/apache/hadoop/crypto/key/RangerKeyStore.java
+++ b/kms/src/main/java/org/apache/hadoop/crypto/key/RangerKeyStore.java
@@ -26,11 +26,13 @@ import java.io.InputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.OutputStream;
+import java.io.Serializable;
import java.io.UnsupportedEncodingException;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
+import java.security.AlgorithmParameters;
import java.security.DigestInputStream;
import java.security.DigestOutputStream;
import java.security.Key;
@@ -39,16 +41,22 @@ import java.security.KeyStoreException;
import java.security.KeyStoreSpi;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
+import java.security.SecureRandom;
import java.security.UnrecoverableKeyException;
import java.security.cert.Certificate;
import java.security.cert.CertificateException;
-import java.util.ArrayList;
import java.util.Date;
import java.util.Enumeration;
import java.util.Hashtable;
import java.util.List;
+import javax.crypto.Cipher;
+import javax.crypto.IllegalBlockSizeException;
import javax.crypto.SealedObject;
+import javax.crypto.SecretKey;
+import javax.crypto.SecretKeyFactory;
+import javax.crypto.spec.PBEKeySpec;
+import javax.crypto.spec.PBEParameterSpec;
import javax.xml.bind.DatatypeConverter;
import org.apache.hadoop.crypto.key.KeyProvider.Metadata;
@@ -108,17 +116,9 @@ public class RangerKeyStore extends KeyStoreSpi {
return null;
}
- Class<?> c = null;
- Object o = null;
try {
- c = Class.forName("com.sun.crypto.provider.KeyProtector");
- Constructor<?> constructor = c.getDeclaredConstructor(char[].class);
- constructor.setAccessible(true);
- o = constructor.newInstance(password);
- Method m = c.getDeclaredMethod("unseal", SealedObject.class);
- m.setAccessible(true);
- key = (Key) m.invoke(o, ((SecretKeyEntry)entry).sealedKey);
- } catch (ClassNotFoundException | NoSuchMethodException | SecurityException | InstantiationException | IllegalAccessException | IllegalArgumentException | InvocationTargetException e) {
+ key = unsealKey(((SecretKeyEntry)entry).sealedKey, password);
+ } catch (Exception e) {
logger.error(e.getMessage());
}
return key;
@@ -144,22 +144,9 @@ public class RangerKeyStore extends KeyStoreSpi {
SecretKeyEntry entry = new SecretKeyEntry();
synchronized(deltaEntries) {
try {
- Class<?> c = null;
- Object o = null;
- try {
- c = Class.forName("com.sun.crypto.provider.KeyProtector");
- Constructor<?> constructor = c.getDeclaredConstructor(char[].class);
- constructor.setAccessible(true);
- o = constructor.newInstance(password);
- } catch (ClassNotFoundException | NoSuchMethodException | SecurityException | InstantiationException | IllegalAccessException | IllegalArgumentException | InvocationTargetException e) {
- logger.error(e.getMessage());
- throw new KeyStoreException(e.getMessage());
- }
entry.date = new Date();
// seal and store the key
- Method m = c.getDeclaredMethod("seal", Key.class);
- m.setAccessible(true);
- entry.sealedKey = (SealedObject) m.invoke(o, key);
+ entry.sealedKey = sealKey(key, password);
entry.cipher_field = cipher;
entry.bit_length = bitLength;
@@ -182,6 +169,47 @@ public class RangerKeyStore extends KeyStoreSpi {
}
}
+ private SealedObject sealKey(Key key, char[] password) throws Exception {
+ // Create SecretKey
+ SecretKeyFactory secretKeyFactory = SecretKeyFactory.getInstance("PBEWithMD5AndTripleDES");
+ PBEKeySpec pbeKeySpec = new PBEKeySpec(password);
+ SecretKey secretKey = secretKeyFactory.generateSecret(pbeKeySpec);
+ pbeKeySpec.clearPassword();
+
+ // Generate random bytes + set up the PBEParameterSpec
+ SecureRandom random = new SecureRandom();
+ byte[] salt = new byte[8];
+ random.nextBytes(salt);
+ PBEParameterSpec pbeSpec = new PBEParameterSpec(salt, 20);
+
+ // Seal the Key
+ Cipher cipher = Cipher.getInstance("PBEWithMD5AndTripleDES");
+ cipher.init(Cipher.ENCRYPT_MODE, secretKey, pbeSpec);
+ return new RangerSealedObject(key, cipher);
+ }
+
+ private Key unsealKey(SealedObject sealedKey, char[] password) throws Exception {
+ // Create SecretKey
+ SecretKeyFactory secretKeyFactory = SecretKeyFactory.getInstance("PBEWithMD5AndTripleDES");
+ PBEKeySpec pbeKeySpec = new PBEKeySpec(password);
+ SecretKey secretKey = secretKeyFactory.generateSecret(pbeKeySpec);
+ pbeKeySpec.clearPassword();
+
+ // Get the AlgorithmParameters from RangerSealedObject
+ AlgorithmParameters algorithmParameters = null;
+ if (sealedKey instanceof RangerSealedObject) {
+ algorithmParameters = ((RangerSealedObject)sealedKey).getParameters();
+ } else {
+ algorithmParameters = new RangerSealedObject(sealedKey).getParameters();
+ }
+
+ // Unseal the Key
+ Cipher cipher = Cipher.getInstance("PBEWithMD5AndTripleDES");
+ cipher.init(Cipher.DECRYPT_MODE, secretKey, algorithmParameters);
+
+ return (Key)sealedKey.getObject(cipher);
+ }
+
@Override
public void engineDeleteEntry(String alias)
throws KeyStoreException
@@ -585,5 +613,30 @@ public class RangerKeyStore extends KeyStoreSpi {
public void clearDeltaEntires(){
deltaEntries.clear();
}
-
+
+ /**
+ * Encapsulate the encrypted key, so that we can retrieve the AlgorithmParameters object on the decryption side
+ */
+ private static class RangerSealedObject extends SealedObject {
+
+ /**
+ *
+ */
+ private static final long serialVersionUID = -7551578543434362070L;
+
+ protected RangerSealedObject(SealedObject so) {
+ super(so);
+ }
+
+ protected RangerSealedObject(Serializable object, Cipher cipher) throws IllegalBlockSizeException, IOException {
+ super(object, cipher);
+ }
+
+ public AlgorithmParameters getParameters() throws NoSuchAlgorithmException, IOException {
+ AlgorithmParameters algorithmParameters = AlgorithmParameters.getInstance("PBEWithMD5AndTripleDES");
+ algorithmParameters.init(super.encodedParams);
+ return algorithmParameters;
+ }
+
+ }
}