Repository: ranger Updated Branches: refs/heads/master c89b55591 -> 6e512b6ab
RANGER-1505 - Remove KeyProtector code in KMS Signed-off-by: Colm O hEigeartaigh <cohei...@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 <cohei...@apache.org> Authored: Mon Apr 10 12:23:38 2017 +0100 Committer: Colm O hEigeartaigh <cohei...@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; + } + + } }