FileEdekInfo(FSDirectory dir, INodeFile inode) throws IOException { assert dir.hasReadLock(); Preconditions.checkNotNull(inode, "INodeFile is null"); inodeId = inode.getId(); final FileEncryptionInfo fei = FSDirEncryptionZoneOp .getFileEncryptionInfo(dir, INodesInPath.fromINode(inode)); Preconditions.checkNotNull(fei, "FileEncryptionInfo is null for " + inodeId); existingEdek = EncryptedKeyVersion .createForDecryption(fei.getKeyName(), fei.getEzKeyVersionName(), fei.getIV(), fei.getEncryptedDataEncryptionKey()); }
@Override public LocalKey createLocalKey(KeyMetadata key) throws IOException { EncryptionAlgorithm algorithm = key.getAlgorithm(); byte[] encryptedKey = new byte[algorithm.getIvLength()]; random.nextBytes(encryptedKey); KeyProviderCryptoExtension.EncryptedKeyVersion param = KeyProviderCryptoExtension.EncryptedKeyVersion.createForDecryption( key.getKeyName(), buildKeyVersionName(key), encryptedKey, algorithm.getZeroKey()); try { KeyProviderCryptoExtension.KeyVersion decryptedKey = ((KeyProviderCryptoExtension) provider) .decryptEncryptedKey(param); return new LocalKey(new SecretKeySpec(decryptedKey.getMaterial(), algorithm.getAlgorithm()), encryptedKey); } catch (GeneralSecurityException e) { throw new IOException("Can't create local encryption key for " + key, e); } }
/** * Decrypts a EDEK by consulting the KeyProvider. */ static KeyVersion decryptEncryptedDataEncryptionKey(FileEncryptionInfo feInfo, KeyProvider keyProvider) throws IOException { if (keyProvider == null) { throw new IOException("No KeyProvider is configured, cannot access" + " an encrypted file"); } EncryptedKeyVersion ekv = EncryptedKeyVersion.createForDecryption( feInfo.getKeyName(), feInfo.getEzKeyVersionName(), feInfo.getIV(), feInfo.getEncryptedDataEncryptionKey()); try { KeyProviderCryptoExtension cryptoProvider = KeyProviderCryptoExtension .createKeyProviderCryptoExtension(keyProvider); return cryptoProvider.decryptEncryptedKey(ekv); } catch (GeneralSecurityException e) { throw new IOException(e); } } }
@Test public void testEncryptDecrypt() throws Exception { // Get an EEK KeyProviderCryptoExtension.EncryptedKeyVersion eek = kpExt.generateEncryptedKey(encryptionKey.getName()); final byte[] encryptedKeyIv = eek.getEncryptedKeyIv(); final byte[] encryptedKeyMaterial = eek.getEncryptedKeyVersion() .getMaterial(); // Decrypt it manually Cipher cipher = Cipher.getInstance("AES/CTR/NoPadding"); cipher.init(Cipher.DECRYPT_MODE, new SecretKeySpec(encryptionKey.getMaterial(), "AES"), new IvParameterSpec(KeyProviderCryptoExtension.EncryptedKeyVersion .deriveIV(encryptedKeyIv))); final byte[] manualMaterial = cipher.doFinal(encryptedKeyMaterial); // Test the createForDecryption factory method EncryptedKeyVersion eek2 = EncryptedKeyVersion.createForDecryption(eek.getEncryptionKeyName(), eek.getEncryptionKeyVersionName(), eek.getEncryptedKeyIv(), eek.getEncryptedKeyVersion().getMaterial()); // Decrypt it with the API KeyVersion decryptedKey = kpExt.decryptEncryptedKey(eek2); final byte[] apiMaterial = decryptedKey.getMaterial(); assertArrayEquals("Wrong key material from decryptEncryptedKey", manualMaterial, apiMaterial); } }
@Test public void testEncryptDecrypt() throws Exception { // Get an EEK KeyProviderCryptoExtension.EncryptedKeyVersion eek = kpExt.generateEncryptedKey(encryptionKey.getName()); final byte[] encryptedKeyIv = eek.getEncryptedKeyIv(); final byte[] encryptedKeyMaterial = eek.getEncryptedKeyVersion() .getMaterial(); // Decrypt it manually Cipher cipher = Cipher.getInstance("AES/CTR/NoPadding"); cipher.init(Cipher.DECRYPT_MODE, new SecretKeySpec(encryptionKey.getMaterial(), "AES"), new IvParameterSpec(KeyProviderCryptoExtension.EncryptedKeyVersion .deriveIV(encryptedKeyIv))); final byte[] manualMaterial = cipher.doFinal(encryptedKeyMaterial); // Test the createForDecryption factory method EncryptedKeyVersion eek2 = EncryptedKeyVersion.createForDecryption(eek.getEncryptionKeyName(), eek.getEncryptionKeyVersionName(), eek.getEncryptedKeyIv(), eek.getEncryptedKeyVersion().getMaterial()); // Decrypt it with the API KeyVersion decryptedKey = kpExt.decryptEncryptedKey(eek2); final byte[] apiMaterial = decryptedKey.getMaterial(); assertArrayEquals("Wrong key material from decryptEncryptedKey", manualMaterial, apiMaterial); } }
/** * Decrypts a EDEK by consulting the KeyProvider. */ private KeyVersion decryptEncryptedDataEncryptionKey(FileEncryptionInfo feInfo) throws IOException { TraceScope scope = Trace.startSpan("decryptEDEK", traceSampler); try { KeyProvider provider = getKeyProvider(); if (provider == null) { throw new IOException("No KeyProvider is configured, cannot access" + " an encrypted file"); } EncryptedKeyVersion ekv = EncryptedKeyVersion.createForDecryption( feInfo.getKeyName(), feInfo.getEzKeyVersionName(), feInfo.getIV(), feInfo.getEncryptedDataEncryptionKey()); try { KeyProviderCryptoExtension cryptoProvider = KeyProviderCryptoExtension .createKeyProviderCryptoExtension(provider); return cryptoProvider.decryptEncryptedKey(ekv); } catch (GeneralSecurityException e) { throw new IOException(e); } } finally { scope.close(); } }
/** * Decrypts a EDEK by consulting the KeyProvider. */ private KeyVersion decryptEncryptedDataEncryptionKey(FileEncryptionInfo feInfo) throws IOException { TraceScope scope = Trace.startSpan("decryptEDEK", traceSampler); try { KeyProvider provider = getKeyProvider(); if (provider == null) { throw new IOException("No KeyProvider is configured, cannot access" + " an encrypted file"); } EncryptedKeyVersion ekv = EncryptedKeyVersion.createForDecryption( feInfo.getKeyName(), feInfo.getEzKeyVersionName(), feInfo.getIV(), feInfo.getEncryptedDataEncryptionKey()); try { KeyProviderCryptoExtension cryptoProvider = KeyProviderCryptoExtension .createKeyProviderCryptoExtension(provider); return cryptoProvider.decryptEncryptedKey(ekv); } catch (GeneralSecurityException e) { throw new IOException(e); } } finally { scope.close(); } }
@Override public Void run() throws Exception { Options opt = newOptions(conf); Map<String, String> m = new HashMap<String, String>(); m.put("key.acl.name", "testKey"); opt.setAttributes(m); KeyVersion kv = kpExt.createKey("foo", SecureRandom.getSeed(16), opt); kpExt.rollNewVersion(kv.getName()); kpExt.rollNewVersion(kv.getName(), SecureRandom.getSeed(16)); EncryptedKeyVersion ekv = kpExt.generateEncryptedKey(kv.getName()); ekv = EncryptedKeyVersion.createForDecryption( ekv.getEncryptionKeyName() + "x", ekv.getEncryptionKeyVersionName(), ekv.getEncryptedKeyIv(), ekv.getEncryptedKeyVersion().getMaterial()); kpExt.decryptEncryptedKey(ekv); return null; } }
@Override public Key decryptLocalKey(KeyMetadata key, byte[] encryptedKey) throws IOException { EncryptionAlgorithm algorithm = key.getAlgorithm(); KeyProviderCryptoExtension.EncryptedKeyVersion param = KeyProviderCryptoExtension.EncryptedKeyVersion.createForDecryption( key.getKeyName(), buildKeyVersionName(key), encryptedKey, algorithm.getZeroKey()); try { KeyProviderCryptoExtension.KeyVersion decrypted = ((KeyProviderCryptoExtension) provider) .decryptEncryptedKey(param); return new SecretKeySpec(decrypted.getMaterial(), algorithm.getAlgorithm()); } catch (GeneralSecurityException e) { return null; } } }
@Override public Void run() throws Exception { Options opt = newOptions(conf); Map<String, String> m = new HashMap<String, String>(); m.put("key.acl.name", "testKey"); opt.setAttributes(m); KeyVersion kv = kpExt.createKey("foo", SecureRandom.getSeed(16), opt); kpExt.rollNewVersion(kv.getName()); kpExt.rollNewVersion(kv.getName(), SecureRandom.getSeed(16)); EncryptedKeyVersion ekv = kpExt.generateEncryptedKey(kv.getName()); ekv = EncryptedKeyVersion.createForDecryption( ekv.getEncryptionKeyName() + "x", ekv.getEncryptionKeyVersionName(), ekv.getEncryptedKeyIv(), ekv.getEncryptedKeyVersion().getMaterial()); kpExt.decryptEncryptedKey(ekv); return null; } }