### Question:
DirectKmsMaterialsProvider implements EncryptionMaterialsProvider { @Override public EncryptionMaterials getEncryptionMaterials(EncryptionContext context) { final Map<String, String> ec = new HashMap<>(); ec.put("*" + CONTENT_KEY_ALGORITHM + "*", dataKeyDesc); ec.put("*" + SIGNING_KEY_ALGORITHM + "*", sigKeyDesc); populateKmsEcFromEc(context, ec); final String keyId = selectEncryptionKeyId(context); if (keyId == null || keyId.isEmpty()) { throw new DynamoDbEncryptionException("Encryption key id is empty."); } final GenerateDataKeyRequest.Builder req = GenerateDataKeyRequest.builder(); req.keyId(keyId); req.numberOfBytes(256 / 8); req.encryptionContext(ec); final GenerateDataKeyResponse dataKeyResult = generateDataKey(req.build(), context); final Map<String, String> materialDescription = new HashMap<>(description); materialDescription.put(COVERED_ATTR_CTX_KEY, KEY_COVERAGE); materialDescription.put(KEY_WRAPPING_ALGORITHM, "kms"); materialDescription.put(CONTENT_KEY_ALGORITHM, dataKeyDesc); materialDescription.put(SIGNING_KEY_ALGORITHM, sigKeyDesc); materialDescription.put(ENVELOPE_KEY, Base64.encodeToString(dataKeyResult.ciphertextBlob().asByteArray())); final Hkdf kdf; try { kdf = Hkdf.getInstance(KDF_ALG); } catch (NoSuchAlgorithmException e) { throw new DynamoDbEncryptionException(e); } kdf.init(dataKeyResult.plaintext().asByteArray()); final SecretKey encryptionKey = new SecretKeySpec(kdf.deriveKey(KDF_ENC_INFO, dataKeyLength / 8), dataKeyAlg); final SecretKey signatureKey = new SecretKeySpec(kdf.deriveKey(KDF_SIG_INFO, sigKeyLength / 8), sigKeyAlg); return new SymmetricRawMaterials(encryptionKey, signatureKey, materialDescription); } DirectKmsMaterialsProvider(KmsClient kms);  DirectKmsMaterialsProvider(KmsClient kms, String encryptionKeyId, Map<String, String> materialDescription);  DirectKmsMaterialsProvider(KmsClient kms, String encryptionKeyId); @Override DecryptionMaterials getDecryptionMaterials(EncryptionContext context); @Override EncryptionMaterials getEncryptionMaterials(EncryptionContext context); @Override void refresh();  }### Answer:
@Test public void randomEnvelopeKeys() { DirectKmsMaterialsProvider prov = new DirectKmsMaterialsProvider(kms, keyId); EncryptionMaterials eMat = prov.getEncryptionMaterials(ctx); SecretKey encryptionKey = eMat.getEncryptionKey(); assertNotNull(encryptionKey); EncryptionMaterials eMat2 = prov.getEncryptionMaterials(ctx); SecretKey encryptionKey2 = eMat2.getEncryptionKey(); assertFalse("Envelope keys must be different", encryptionKey.equals(encryptionKey2)); }
@Test(expectedExceptions = DynamoDbEncryptionException.class) public void missingEncryptionKeyId() { ExtendedKmsMaterialProvider prov = new ExtendedKmsMaterialProvider(kms, keyId, "encryptionKeyId"); Map<String, AttributeValue> attrVals = new HashMap<>(); attrVals.put("hk", AttributeValue.builder().n("10").build()); attrVals.put("rk", AttributeValue.builder().n("20").build()); ctx = EncryptionContext.builder().hashKeyName("hk").rangeKeyName("rk") .tableName("KmsTableName").attributeValues(attrVals).build(); prov.getEncryptionMaterials(ctx); }