Exemple #1
0
        private async Task <TransactionalBatchResponse> DecryptTransactionalBatchResponseAsync(
            TransactionalBatchResponse response,
            CosmosDiagnosticsContext diagnosticsContext,
            CancellationToken cancellationToken)
        {
            List <TransactionalBatchOperationResult> decryptedTransactionalBatchOperationResults = new List <TransactionalBatchOperationResult>();

            for (int index = 0; index < response.Count; index++)
            {
                TransactionalBatchOperationResult result = response[index];

                if (response.IsSuccessStatusCode && result.ResourceStream != null)
                {
                    (Stream decryptedStream, _) = await EncryptionProcessor.DecryptAsync(
                        result.ResourceStream,
                        this.encryptor,
                        diagnosticsContext,
                        cancellationToken);

                    result = new EncryptionTransactionalBatchOperationResult(response[index], decryptedStream);
                }

                decryptedTransactionalBatchOperationResults.Add(result);
            }

            return(new EncryptionTransactionalBatchResponse(
                       decryptedTransactionalBatchOperationResults,
                       response,
                       this.cosmosSerializer));
        }
Exemple #2
0
        public override TransactionalBatch CreateItemStream(
            Stream streamPayload,
            TransactionalBatchItemRequestOptions requestOptions = null)
        {
            if (requestOptions is EncryptionTransactionalBatchItemRequestOptions encryptionItemRequestOptions &&
                encryptionItemRequestOptions.EncryptionOptions != null)
            {
                CosmosDiagnosticsContext diagnosticsContext = CosmosDiagnosticsContext.Create(requestOptions);
                using (diagnosticsContext.CreateScope("EncryptItemStream"))
                {
                    streamPayload = EncryptionProcessor.EncryptAsync(
                        streamPayload,
                        this.encryptor,
                        encryptionItemRequestOptions.EncryptionOptions,
                        diagnosticsContext,
                        cancellationToken: default).Result;
                }
            }

            this.transactionalBatch = this.transactionalBatch.CreateItemStream(
                streamPayload,
                requestOptions);

            return(this);
        }
        private async Task <ResponseMessage> ReadItemHelperAsync(
            string id,
            PartitionKey partitionKey,
            ItemRequestOptions requestOptions,
            bool decryptResponse,
            CosmosDiagnosticsContext diagnosticsContext,
            CancellationToken cancellationToken)
        {
            ResponseMessage responseMessage = await this.container.ReadItemStreamAsync(
                id,
                partitionKey,
                requestOptions,
                cancellationToken);

            if (decryptResponse)
            {
                (responseMessage.Content, _) = await EncryptionProcessor.DecryptAsync(
                    responseMessage.Content,
                    this.Encryptor,
                    diagnosticsContext,
                    cancellationToken);
            }

            return(responseMessage);
        }
Exemple #4
0
        internal static async Task <Stream> DeserializeAndDecryptResponseAsync(
            Stream content,
            Encryptor encryptor,
            CancellationToken cancellationToken)
        {
            JObject contentJObj = EncryptionProcessor.BaseSerializer.FromStream <JObject>(content);

            if (!(contentJObj.SelectToken(Constants.DocumentsResourcePropertyName) is JArray documents))
            {
                throw new InvalidOperationException("Feed Response body contract was violated. Feed response did not have an array of Documents");
            }

            foreach (JToken value in documents)
            {
                if (!(value is JObject document))
                {
                    continue;
                }

                CosmosDiagnosticsContext diagnosticsContext = CosmosDiagnosticsContext.Create(null);
                using (diagnosticsContext.CreateScope("EncryptionProcessor.DeserializeAndDecryptResponseAsync"))
                {
                    await EncryptionProcessor.DecryptAsync(
                        document,
                        encryptor,
                        diagnosticsContext,
                        cancellationToken);
                }
            }

            // the contents of contentJObj get decrypted in place for MDE algorithm model, and for legacy model _ei property is removed
            // and corresponding decrypted properties are added back in the documents.
            return(EncryptionProcessor.BaseSerializer.ToStream(contentJObj));
        }
        private async Task <TransactionalBatchResponse> DecryptTransactionalBatchResponseAsync(
            TransactionalBatchResponse response,
            CosmosDiagnosticsContext diagnosticsContext,
            CancellationToken cancellationToken)
        {
            List <TransactionalBatchOperationResult> decryptedTransactionalBatchOperationResults = new List <TransactionalBatchOperationResult>();

            foreach (TransactionalBatchOperationResult result in response)
            {
                if (response.IsSuccessStatusCode && result.ResourceStream != null)
                {
                    (Stream decryptedStream, _) = await EncryptionProcessor.DecryptAsync(
                        result.ResourceStream,
                        this.encryptor,
                        diagnosticsContext,
                        cancellationToken);

                    decryptedTransactionalBatchOperationResults.Add(new EncryptionTransactionalBatchOperationResult(result, decryptedStream));
                }
                else
                {
                    decryptedTransactionalBatchOperationResults.Add(result);
                }
            }

            return(new EncryptionTransactionalBatchResponse(
                       decryptedTransactionalBatchOperationResults,
                       response,
                       this.cosmosSerializer));
        }
Exemple #6
0
        private static async Task <DecryptionContext> MdeEncAlgoDecryptObjectAsync(
            JObject document,
            Encryptor encryptor,
            EncryptionProperties encryptionProperties,
            CosmosDiagnosticsContext diagnosticsContext,
            CancellationToken cancellationToken)
        {
            JObject plainTextJObj = new JObject();

            foreach (string path in encryptionProperties.EncryptedPaths)
            {
                string propertyName = path.Substring(1);
                if (!document.TryGetValue(propertyName, out JToken propertyValue))
                {
                    throw new InvalidOperationException($"{nameof(encryptionProperties.EncryptedPaths)} includes a path: '{path}' which was not found.");
                }

                byte[] cipherTextWithTypeMarker = propertyValue.ToObject <byte[]>();

                if (cipherTextWithTypeMarker == null)
                {
                    continue;
                }

                byte[] cipherText = new byte[cipherTextWithTypeMarker.Length - 1];
                Buffer.BlockCopy(cipherTextWithTypeMarker, 1, cipherText, 0, cipherTextWithTypeMarker.Length - 1);

                byte[] plainText = await EncryptionProcessor.MdeEncAlgoDecryptPropertyAsync(
                    encryptionProperties,
                    cipherText,
                    encryptor,
                    diagnosticsContext,
                    cancellationToken);

                EncryptionProcessor.DeserializeAndAddProperty(
                    (TypeMarker)cipherTextWithTypeMarker[0],
                    plainText,
                    plainTextJObj,
                    propertyName);
            }

            List <string> pathsDecrypted = new List <string>();

            foreach (JProperty property in plainTextJObj.Properties())
            {
                document[property.Name] = property.Value;
                pathsDecrypted.Add("/" + property.Name);
            }

            DecryptionContext decryptionContext = EncryptionProcessor.CreateDecryptionContext(
                pathsDecrypted,
                encryptionProperties.DataEncryptionKeyId);

            document.Remove(Constants.EncryptedInfo);
            return(decryptionContext);
        }
Exemple #7
0
        /// <remarks>
        /// If there isn't any data that needs to be decrypted, input stream will be returned without any modification.
        /// Else input stream will be disposed, and a new stream is returned.
        /// In case of an exception, input stream won't be disposed, but position will be end of stream.
        /// </remarks>
        public static async Task <(Stream, DecryptionContext)> DecryptAsync(
            Stream input,
            Encryptor encryptor,
            CosmosDiagnosticsContext diagnosticsContext,
            CancellationToken cancellationToken)
        {
            if (input == null)
            {
                return(input, null);
            }

            Debug.Assert(input.CanSeek);
            Debug.Assert(encryptor != null);
            Debug.Assert(diagnosticsContext != null);

            JObject itemJObj = EncryptionProcessor.RetrieveItem(input);
            JObject encryptionPropertiesJObj = EncryptionProcessor.RetrieveEncryptionProperties(itemJObj);

            if (encryptionPropertiesJObj == null)
            {
                input.Position = 0;
                return(input, null);
            }

            EncryptionProperties encryptionProperties = encryptionPropertiesJObj.ToObject <EncryptionProperties>();
            DecryptionContext    decryptionContext;

            switch (encryptionProperties.EncryptionAlgorithm)
            {
            case CosmosEncryptionAlgorithm.MdeAeadAes256CbcHmac256Randomized:
                decryptionContext = await EncryptionProcessor.MdeEncAlgoDecryptObjectAsync(
                    itemJObj,
                    encryptor,
                    encryptionProperties,
                    diagnosticsContext,
                    cancellationToken);

                break;

            case CosmosEncryptionAlgorithm.AEAes256CbcHmacSha256Randomized:
                decryptionContext = await EncryptionProcessor.LegacyEncAlgoDecryptContentAsync(
                    itemJObj,
                    encryptionProperties,
                    encryptor,
                    diagnosticsContext,
                    cancellationToken);

                break;

            default:
                throw new NotSupportedException($"Encryption Algorithm : {encryptionProperties.EncryptionAlgorithm} is not supported.");
            }

            input.Dispose();
            return(EncryptionProcessor.BaseSerializer.ToStream(itemJObj), decryptionContext);
        }
        private async Task <ResponseMessage> ReplaceItemHelperAsync(
            Stream streamPayload,
            string id,
            PartitionKey partitionKey,
            ItemRequestOptions requestOptions,
            bool decryptResponse,
            CosmosDiagnosticsContext diagnosticsContext,
            CancellationToken cancellationToken)
        {
            if (!(requestOptions is EncryptionItemRequestOptions encryptionItemRequestOptions) ||
                encryptionItemRequestOptions.EncryptionOptions == null)
            {
                return(await this.container.ReplaceItemStreamAsync(
                           streamPayload,
                           id,
                           partitionKey,
                           requestOptions,
                           cancellationToken));
            }

            if (partitionKey == null)
            {
                throw new NotSupportedException($"{nameof(partitionKey)} cannot be null for operations using {nameof(EncryptionContainer)}.");
            }

            streamPayload = await EncryptionProcessor.EncryptAsync(
                streamPayload,
                this.Encryptor,
                encryptionItemRequestOptions.EncryptionOptions,
                diagnosticsContext,
                cancellationToken);

            ResponseMessage responseMessage = await this.container.ReplaceItemStreamAsync(
                streamPayload,
                id,
                partitionKey,
                requestOptions,
                cancellationToken);

            if (decryptResponse)
            {
                (responseMessage.Content, _) = await EncryptionProcessor.DecryptAsync(
                    responseMessage.Content,
                    this.Encryptor,
                    diagnosticsContext,
                    cancellationToken);
            }

            return(responseMessage);
        }
        internal static async Task <Stream> DeserializeAndDecryptResponseAsync(
            Stream content,
            Encryptor encryptor,
            CancellationToken cancellationToken)
        {
            JObject contentJObj = EncryptionProcessor.BaseSerializer.FromStream <JObject>(content);
            JArray  result      = new JArray();

            if (!(contentJObj.SelectToken(Constants.DocumentsResourcePropertyName) is JArray documents))
            {
                throw new InvalidOperationException("Feed Response body contract was violated. Feed response did not have an array of Documents");
            }

            foreach (JToken value in documents)
            {
                if (!(value is JObject document))
                {
                    result.Add(value);
                    continue;
                }

                CosmosDiagnosticsContext diagnosticsContext = CosmosDiagnosticsContext.Create(null);
                using (diagnosticsContext.CreateScope("EncryptionProcessor.DeserializeAndDecryptResponseAsync"))
                {
                    (JObject decryptedDocument, DecryptionContext _) = await EncryptionProcessor.DecryptAsync(
                        document,
                        encryptor,
                        diagnosticsContext,
                        cancellationToken);

                    result.Add(decryptedDocument);
                }
            }

            JObject decryptedResponse = new JObject();

            foreach (JProperty property in contentJObj.Properties())
            {
                if (property.Name.Equals(Constants.DocumentsResourcePropertyName))
                {
                    decryptedResponse.Add(property.Name, (JToken)result);
                }
                else
                {
                    decryptedResponse.Add(property.Name, property.Value);
                }
            }

            return(EncryptionProcessor.BaseSerializer.ToStream(decryptedResponse));
        }
Exemple #10
0
        public static async Task <(JObject, DecryptionContext)> DecryptAsync(
            JObject document,
            Encryptor encryptor,
            CosmosDiagnosticsContext diagnosticsContext,
            CancellationToken cancellationToken)
        {
            Debug.Assert(document != null);

            Debug.Assert(encryptor != null);

            JObject encryptionPropertiesJObj = EncryptionProcessor.RetrieveEncryptionProperties(document);

            if (encryptionPropertiesJObj == null)
            {
                return(document, null);
            }

            EncryptionProperties encryptionProperties = encryptionPropertiesJObj.ToObject <EncryptionProperties>();

            DecryptionContext decryptionContext;

            switch (encryptionProperties.EncryptionAlgorithm)
            {
            case CosmosEncryptionAlgorithm.MdeAeadAes256CbcHmac256Randomized:
                decryptionContext = await EncryptionProcessor.MdeEncAlgoDecryptObjectAsync(
                    document,
                    encryptor,
                    encryptionProperties,
                    diagnosticsContext,
                    cancellationToken);

                break;

            case CosmosEncryptionAlgorithm.AEAes256CbcHmacSha256Randomized:
                decryptionContext = await EncryptionProcessor.LegacyEncAlgoDecryptContentAsync(
                    document,
                    encryptionProperties,
                    encryptor,
                    diagnosticsContext,
                    cancellationToken);

                break;

            default:
                throw new NotSupportedException($"Encryption Algorithm : {encryptionProperties.EncryptionAlgorithm} is not supported.");
            }

            return(document, decryptionContext);
        }
Exemple #11
0
        private static async Task <DecryptionContext> LegacyEncAlgoDecryptContentAsync(
            JObject document,
            EncryptionProperties encryptionProperties,
            Encryptor encryptor,
            CosmosDiagnosticsContext diagnosticsContext,
            CancellationToken cancellationToken)
        {
            if (encryptionProperties.EncryptionFormatVersion != 2)
            {
                throw new NotSupportedException($"Unknown encryption format version: {encryptionProperties.EncryptionFormatVersion}. Please upgrade your SDK to the latest version.");
            }

            byte[] plainText = await encryptor.DecryptAsync(
                encryptionProperties.EncryptedData,
                encryptionProperties.DataEncryptionKeyId,
                encryptionProperties.EncryptionAlgorithm,
                cancellationToken);

            if (plainText == null)
            {
                throw new InvalidOperationException($"{nameof(Encryptor)} returned null plainText from {nameof(DecryptAsync)}.");
            }

            JObject plainTextJObj;

            using (MemoryStream memoryStream = new MemoryStream(plainText))
                using (StreamReader streamReader = new StreamReader(memoryStream))
                    using (JsonTextReader jsonTextReader = new JsonTextReader(streamReader))
                    {
                        plainTextJObj = JObject.Load(jsonTextReader);
                    }

            List <string> pathsDecrypted = new List <string>();

            foreach (JProperty property in plainTextJObj.Properties())
            {
                document.Add(property.Name, property.Value);
                pathsDecrypted.Add("/" + property.Name);
            }

            DecryptionContext decryptionContext = EncryptionProcessor.CreateDecryptionContext(
                pathsDecrypted,
                encryptionProperties.DataEncryptionKeyId);

            document.Remove(Constants.EncryptedInfo);

            return(decryptionContext);
        }
        public override ChangeFeedProcessorBuilder GetChangeFeedProcessorBuilder <T>(
            string processorName,
            ChangesHandler <T> onChangesDelegate)
        {
            CosmosDiagnosticsContext diagnosticsContext = CosmosDiagnosticsContext.Create(null);

            using (diagnosticsContext.CreateScope("GetChangeFeedProcessorBuilder"))
            {
                return(this.container.GetChangeFeedProcessorBuilder(
                           processorName,
                           async(IReadOnlyCollection <JObject> documents, CancellationToken cancellationToken) =>
                {
                    List <T> decryptItems = new List <T>(documents.Count);
                    if (typeof(T) == typeof(DecryptableItem))
                    {
                        foreach (JToken value in documents)
                        {
                            DecryptableItemCore item = new DecryptableItemCore(
                                value,
                                this.Encryptor,
                                this.CosmosSerializer);

                            decryptItems.Add((T)(object)item);
                        }
                    }
                    else
                    {
                        foreach (JObject document in documents)
                        {
                            (JObject decryptedDocument, DecryptionContext _) = await EncryptionProcessor.DecryptAsync(
                                document,
                                this.Encryptor,
                                diagnosticsContext,
                                cancellationToken);

                            decryptItems.Add(decryptedDocument.ToObject <T>());
                        }
                    }

                    // Call the original passed in delegate
                    await onChangesDelegate(decryptItems, cancellationToken);
                }));
            }
        }
        private async Task <ResponseMessage> CreateItemHelperAsync(
            Stream streamPayload,
            PartitionKey partitionKey,
            ItemRequestOptions requestOptions,
            bool decryptResponse,
            CosmosDiagnosticsContext diagnosticsContext,
            CancellationToken cancellationToken)
        {
            if (!(requestOptions is EncryptionItemRequestOptions encryptionItemRequestOptions) ||
                encryptionItemRequestOptions.EncryptionOptions == null)
            {
                return(await this.container.CreateItemStreamAsync(
                           streamPayload,
                           partitionKey,
                           requestOptions,
                           cancellationToken));
            }

            streamPayload = await EncryptionProcessor.EncryptAsync(
                streamPayload,
                this.Encryptor,
                encryptionItemRequestOptions.EncryptionOptions,
                diagnosticsContext,
                cancellationToken);

            ResponseMessage responseMessage = await this.container.CreateItemStreamAsync(
                streamPayload,
                partitionKey,
                requestOptions,
                cancellationToken);

            if (decryptResponse)
            {
                (responseMessage.Content, _) = await EncryptionProcessor.DecryptAsync(
                    responseMessage.Content,
                    this.Encryptor,
                    diagnosticsContext,
                    cancellationToken);
            }

            return(responseMessage);
        }
Exemple #14
0
        public override ChangeFeedProcessorBuilder GetChangeFeedProcessorBuilder(
            string processorName,
            ChangeFeedStreamHandler onChangesDelegate)
        {
            return(this.container.GetChangeFeedProcessorBuilder(
                       processorName,
                       async(
                           ChangeFeedProcessorContext context,
                           Stream changes,
                           CancellationToken cancellationToken) =>
            {
                Stream decryptedChanges = await EncryptionProcessor.DeserializeAndDecryptResponseAsync(
                    changes,
                    this.Encryptor,
                    cancellationToken);

                // Call the original passed in delegate
                await onChangesDelegate(context, decryptedChanges, cancellationToken);
            }));
        }
        public override async Task <ResponseMessage> ReadNextAsync(CancellationToken cancellationToken = default)
        {
            CosmosDiagnosticsContext diagnosticsContext = CosmosDiagnosticsContext.Create(options: null);

            using (diagnosticsContext.CreateScope("FeedIterator.ReadNext"))
            {
                ResponseMessage responseMessage = await this.feedIterator.ReadNextAsync(cancellationToken);

                if (responseMessage.IsSuccessStatusCode && responseMessage.Content != null)
                {
                    Stream decryptedContent = await EncryptionProcessor.DeserializeAndDecryptResponseAsync(
                        responseMessage.Content,
                        this.encryptor,
                        cancellationToken);

                    return(new DecryptedResponseMessage(responseMessage, decryptedContent));
                }

                return(responseMessage);
            }
        }
Exemple #16
0
        /// <remarks>
        /// If there isn't any PathsToEncrypt, input stream will be returned without any modification.
        /// Else input stream will be disposed, and a new stream is returned.
        /// In case of an exception, input stream won't be disposed, but position will be end of stream.
        /// </remarks>
        public static async Task <Stream> EncryptAsync(
            Stream input,
            Encryptor encryptor,
            EncryptionOptions encryptionOptions,
            CosmosDiagnosticsContext diagnosticsContext,
            CancellationToken cancellationToken)
        {
            EncryptionProcessor.ValidateInputForEncrypt(
                input,
                encryptor,
                encryptionOptions);

            if (!encryptionOptions.PathsToEncrypt.Any())
            {
                return(input);
            }

            if (!encryptionOptions.PathsToEncrypt.Distinct().SequenceEqual(encryptionOptions.PathsToEncrypt))
            {
                throw new InvalidOperationException("Duplicate paths in PathsToEncrypt passed via EncryptionOptions.");
            }

            foreach (string path in encryptionOptions.PathsToEncrypt)
            {
                if (string.IsNullOrWhiteSpace(path) || path[0] != '/' || path.LastIndexOf('/') != 0)
                {
                    throw new InvalidOperationException($"Invalid path {path ?? string.Empty}, {nameof(encryptionOptions.PathsToEncrypt)}");
                }

                if (string.Equals(path.Substring(1), "id"))
                {
                    throw new InvalidOperationException($"{nameof(encryptionOptions.PathsToEncrypt)} includes a invalid path: '{path}'.");
                }
            }

            JObject              itemJObj             = EncryptionProcessor.BaseSerializer.FromStream <JObject>(input);
            List <string>        pathsEncrypted       = new List <string>();
            EncryptionProperties encryptionProperties = null;

            byte[]     plainText  = null;
            byte[]     cipherText = null;
            TypeMarker typeMarker;

            switch (encryptionOptions.EncryptionAlgorithm)
            {
            case CosmosEncryptionAlgorithm.MdeAeadAes256CbcHmac256Randomized:

                foreach (string pathToEncrypt in encryptionOptions.PathsToEncrypt)
                {
                    string propertyName = pathToEncrypt.Substring(1);
                    if (!itemJObj.TryGetValue(propertyName, out JToken propertyValue))
                    {
                        throw new ArgumentException($"{nameof(encryptionOptions.PathsToEncrypt)} includes a path: '{pathToEncrypt}' which was not found.");
                    }

                    if (propertyValue.Type == JTokenType.Null)
                    {
                        continue;
                    }

                    (typeMarker, plainText) = EncryptionProcessor.Serialize(propertyValue);

                    cipherText = await encryptor.EncryptAsync(
                        plainText,
                        encryptionOptions.DataEncryptionKeyId,
                        encryptionOptions.EncryptionAlgorithm);

                    if (cipherText == null)
                    {
                        throw new InvalidOperationException($"{nameof(Encryptor)} returned null cipherText from {nameof(EncryptAsync)}.");
                    }

                    byte[] cipherTextWithTypeMarker = new byte[cipherText.Length + 1];
                    cipherTextWithTypeMarker[0] = (byte)typeMarker;
                    Buffer.BlockCopy(cipherText, 0, cipherTextWithTypeMarker, 1, cipherText.Length);
                    itemJObj[propertyName] = cipherTextWithTypeMarker;
                    pathsEncrypted.Add(pathToEncrypt);
                }

                encryptionProperties = new EncryptionProperties(
                    encryptionFormatVersion: 3,
                    encryptionOptions.EncryptionAlgorithm,
                    encryptionOptions.DataEncryptionKeyId,
                    encryptedData: null,
                    pathsEncrypted);
                break;

            case CosmosEncryptionAlgorithm.AEAes256CbcHmacSha256Randomized:

                JObject toEncryptJObj = new JObject();

                foreach (string pathToEncrypt in encryptionOptions.PathsToEncrypt)
                {
                    string propertyName = pathToEncrypt.Substring(1);
                    if (!itemJObj.TryGetValue(propertyName, out JToken propertyValue))
                    {
                        throw new ArgumentException($"{nameof(encryptionOptions.PathsToEncrypt)} includes a path: '{pathToEncrypt}' which was not found.");
                    }

                    toEncryptJObj.Add(propertyName, propertyValue.Value <JToken>());
                    itemJObj.Remove(propertyName);
                }

                MemoryStream memoryStream = EncryptionProcessor.BaseSerializer.ToStream <JObject>(toEncryptJObj);
                Debug.Assert(memoryStream != null);
                Debug.Assert(memoryStream.TryGetBuffer(out _));
                plainText = memoryStream.ToArray();

                cipherText = await encryptor.EncryptAsync(
                    plainText,
                    encryptionOptions.DataEncryptionKeyId,
                    encryptionOptions.EncryptionAlgorithm,
                    cancellationToken);

                if (cipherText == null)
                {
                    throw new InvalidOperationException($"{nameof(Encryptor)} returned null cipherText from {nameof(EncryptAsync)}.");
                }

                encryptionProperties = new EncryptionProperties(
                    encryptionFormatVersion: 2,
                    encryptionOptions.EncryptionAlgorithm,
                    encryptionOptions.DataEncryptionKeyId,
                    encryptedData: cipherText,
                    encryptionOptions.PathsToEncrypt);
                break;

            default:
                throw new NotSupportedException($"Encryption Algorithm : {encryptionOptions.EncryptionAlgorithm} is not supported.");
            }

            itemJObj.Add(Constants.EncryptedInfo, JObject.FromObject(encryptionProperties));
            input.Dispose();
            return(EncryptionProcessor.BaseSerializer.ToStream(itemJObj));
        }