public ConsumeContext Deserialize(ReceiveContext receiveContext)
        {
            try
            {
                MessageEnvelope envelope;
                using (Stream body = receiveContext.GetBodyStream())
                    using (Stream cryptoStream = _provider.GetDecryptStream(body, receiveContext))
                        using (var jsonReader = new BsonDataReader(cryptoStream))
                        {
                            envelope = _deserializer.Deserialize <MessageEnvelope>(jsonReader);
                        }

                return(new JsonConsumeContext(_deserializer, receiveContext, envelope));
            }
            catch (JsonSerializationException ex)
            {
                throw new SerializationException("A JSON serialization exception occurred while deserializing the message envelope", ex);
            }
            catch (SerializationException)
            {
                throw;
            }
            catch (Exception ex)
            {
                throw new SerializationException("An exception occurred while deserializing the message envelope", ex);
            }
        }
        public async Task <Stream> Get(Uri address, CancellationToken cancellationToken = new CancellationToken())
        {
            var stream = await _repository.Get(address, cancellationToken).ConfigureAwait(false);

            address.TryGetValueFromQueryString("keyId", out var keyId);

            return(_streamProvider.GetDecryptStream(stream, keyId, CryptoStreamMode.Read));
        }
        /// <summary>
        /// Returns a stream for decrypting the message
        /// </summary>
        /// <param name="provider">The crypto stream provider</param>
        /// <param name="stream">The original stream to which the encrypted message content is written</param>
        /// <param name="context">The second context of the message</param>
        /// <returns>A stream for serializing the message which will be encrypted</returns>
        public static Stream GetDecryptStream(this ICryptoStreamProvider provider, Stream stream, TransformContext context)
        {
            if (context == null)
            {
                throw new ArgumentNullException(nameof(context));
            }

            var keyId = context.Headers.TryGetHeader(EncryptedMessageSerializer.EncryptionKeyHeader, out var keyIdObj)
                ? keyIdObj.ToString()
                : default;

            return(provider.GetDecryptStream(stream, keyId, CryptoStreamMode.Read));
        }