@Override
  public ByteBuffer encrypt(ByteBuffer buffer) throws GeneralSecurityException {
    Object key = kms.getRandomKey();
    ByteBuffer encryptedKey = cryptoService.encryptKey(key, contextKey);
    ByteBuffer encryptedDataBuffer = cryptoService.encrypt(buffer, key);
    ByteBuffer output = ByteBuffer.allocate(
        EncryptedDataPayload.OVERHEAD_LENGTH + encryptedKey.array().length + encryptedDataBuffer.array().length);
    EncryptedDataPayload.serialize(output, new EncryptedDataPayload(encryptedKey, encryptedDataBuffer));
    output.flip();
    return output;
  }
Implementation of CloudBlobCryptoAgent, encrypts byte buffers by
1. generating a random encryption key
2. encrypting that random key with a key from KeyManagementService
   that is associated with the given context string
3. encrypting a data byte buffer with the generated random key
4. returning a byte buffer containing the serialized encrypted key
   and encrypted data (see {@link EncryptedDataPayload} below
   for serialization description
ambry-cloud/src/main/java/com/github/ambry/cloud/CloudBlobCryptoAgentImpl.java