/**
  * Returns the original crypto scheme used for encryption, which may differ from the crypto scheme
  * used for decryption during, for example, a range-get operation.
  *
  * @param instructionFile the instruction file of the s3 object; or null if there is none.
  */
 ContentCryptoScheme encryptionSchemeOf(Map<String, String> instructionFile) {
   if (instructionFile != null) {
     String cekAlgo = instructionFile.get(Headers.CRYPTO_CEK_ALGORITHM);
     return ContentCryptoScheme.fromCEKAlgo(cekAlgo);
   }
   ObjectMetadata meta = s3obj.getObjectMetadata();
   Map<String, String> userMeta = meta.getUserMetadata();
   String cekAlgo = userMeta.get(Headers.CRYPTO_CEK_ALGORITHM);
   return ContentCryptoScheme.fromCEKAlgo(cekAlgo);
 }
 protected final SecretKey generateCEK() {
   KeyGenerator generator;
   try {
     generator = KeyGenerator.getInstance(contentCryptoScheme.getKeyGeneratorAlgorithm());
     generator.init(contentCryptoScheme.getKeyLengthInBits(), cryptoScheme.getSecureRandom());
     return generator.generateKey();
   } catch (NoSuchAlgorithmException e) {
     throw new AmazonClientException(
         "Unable to generate envelope symmetric key:" + e.getMessage(), e);
   }
 }
 /**
  * Generates and returns the content encryption material with the given kek material and security
  * providers.
  */
 protected final ContentCryptoMaterial newContentCryptoMaterial(
     EncryptionMaterialsProvider kekMaterialProvider, Provider provider) {
   // Generate a one-time use symmetric key and initialize a cipher to encrypt object data
   SecretKey cek = generateCEK();
   // Randomly generate the IV
   byte[] iv = new byte[contentCryptoScheme.getIVLengthInBytes()];
   cryptoScheme.getSecureRandom().nextBytes(iv);
   // Encrypt the envelope symmetric key
   EncryptionMaterials kekMaterials = kekMaterialProvider.getEncryptionMaterials();
   SecuredCEK cekSecured = secureCEK(cek, kekMaterials, provider);
   // Return a new instruction with the appropriate fields.
   return new ContentCryptoMaterial(
       kekMaterials.getMaterialsDescription(),
       cekSecured.encrypted,
       cekSecured.keyWrapAlgorithm,
       contentCryptoScheme.createCipherLite(cek, iv, Cipher.ENCRYPT_MODE, provider));
 }