static EncryptedDataPayload deserialize(ByteBuffer inputBuffer) throws GeneralSecurityException {
      int startOffset = inputBuffer.position();
      CRC32 crc = new CRC32();
      try {
        short version = inputBuffer.getShort();
        if (version != 1) {
          throw new GeneralSecurityException("Unrecognized version: " + version);
        }
        int encryptedKeySize = inputBuffer.getInt();
        int encryptedDataSize = (int) inputBuffer.getLong();
        if (encryptedKeySize < 0) {
          throw new GeneralSecurityException("Encrypted key size is less than 0");
        }
        if (encryptedDataSize < 0) {
          throw new GeneralSecurityException("Encrypted data size is less than 0");
        }
        byte[] encryptedKey = new byte[encryptedKeySize];
        byte[] encryptedData = new byte[encryptedDataSize];
        inputBuffer.get(encryptedKey);
        inputBuffer.get(encryptedData);
        crc.update(inputBuffer.array(), startOffset, INITIAL_MESSAGE_LENGTH + encryptedKeySize + encryptedDataSize);
        long expectedCrc = inputBuffer.getLong();
        long actualCrc = crc.getValue();
        if (actualCrc != expectedCrc) {
          throw new GeneralSecurityException(
              "Encrypted blob is corrupt.  ExpectedCRC: " + expectedCrc + " ActualCRC: " + actualCrc);
        }
        return new EncryptedDataPayload(ByteBuffer.wrap(encryptedKey), ByteBuffer.wrap(encryptedData));
      } catch (RuntimeException rex) {
        throw new GeneralSecurityException("Reading payload from buffer", rex);
      }
    }
Deserialize an {@link EncryptedDataPayload} from an input buffer.
@param inputBuffer the {@link ByteBuffer} to read from.  Currently, only HeapByteBuffer is supported.
@return the deserialized {@link EncryptedDataPayload}.
@throws GeneralSecurityException if the buffer does not have the expected size or format.
ambry-cloud/src/main/java/com/github/ambry/cloud/CloudBlobCryptoAgentImpl.java