Esempio n. 1
0
        public static async Task <JObject> DecryptAsync(
            JObject document,
            Encryptor encryptor,
            CosmosDiagnosticsContext diagnosticsContext,
            IReadOnlyDictionary <List <string>, string> pathsToEncrypt,
            CancellationToken cancellationToken)
        {
            Debug.Assert(document != null);
            Debug.Assert(encryptor != null);
            Debug.Assert(diagnosticsContext != null);

            foreach (List <string> paths in pathsToEncrypt.Keys)
            {
                foreach (string path in paths)
                {
                    if (document.TryGetValue(path.Substring(1), out JToken propertyValue))
                    {
                        EncryptionProperties encryptionProperties = new EncryptionProperties(
                            encryptionFormatVersion: 2,
                            CosmosEncryptionAlgorithm.AEAD_AES_256_CBC_HMAC_SHA256,
                            pathsToEncrypt[paths],
                            propertyValue.ToObject <byte[]>(),
                            path);

                        JObject propPlainTextJObj = await PropertyEncryptionProcessor.DecryptContentAsync(
                            encryptionProperties,
                            encryptor,
                            diagnosticsContext,
                            cancellationToken);

                        foreach (JProperty property in propPlainTextJObj.Properties())
                        {
                            document[property.Name] = property.Value;
                        }
                    }
                }
            }

            if (document.TryGetValue(Constants.EncryptedInfo, out JToken encryptedInfo))
            {
                EncryptionProperties encryptionProperties = JsonConvert.DeserializeObject <EncryptionProperties>(encryptedInfo.ToString());

                JObject plainTextJObj = await PropertyEncryptionProcessor.DecryptContentAsync(
                    encryptionProperties,
                    encryptor,
                    diagnosticsContext,
                    cancellationToken);

                document.Remove(Constants.EncryptedInfo);

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

            return(document);
        }
Esempio n. 2
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> DecryptAsync(
            Stream input,
            Encryptor encryptor,
            CosmosDiagnosticsContext diagnosticsContext,
            IReadOnlyDictionary <List <string>, string> pathsToEncrypt,
            CancellationToken cancellationToken)
        {
            Debug.Assert(input != null);
            Debug.Assert(input.CanSeek);
            Debug.Assert(encryptor != null);
            Debug.Assert(diagnosticsContext != null);

            JObject itemJObj;

            using (StreamReader sr = new StreamReader(input, Encoding.UTF8, detectEncodingFromByteOrderMarks: true, bufferSize: 1024, leaveOpen: true))
            {
                using JsonTextReader jsonTextReader = new JsonTextReader(sr);
                itemJObj = JsonSerializer.Create().Deserialize <JObject>(jsonTextReader);
            }

            if (pathsToEncrypt != null)
            {
                foreach (List <string> paths in pathsToEncrypt.Keys)
                {
                    foreach (string path in paths)
                    {
                        if (itemJObj.TryGetValue(path.Substring(1), out JToken propertyValue))
                        {
                            EncryptionProperties encryptionProperties = new EncryptionProperties(
                                encryptionFormatVersion: 2,
                                CosmosEncryptionAlgorithm.AEAD_AES_256_CBC_HMAC_SHA256,
                                pathsToEncrypt[paths],
                                propertyValue.ToObject <byte[]>(),
                                path);

                            JObject propPlainTextJObj = await PropertyEncryptionProcessor.DecryptContentAsync(
                                encryptionProperties,
                                encryptor,
                                diagnosticsContext,
                                cancellationToken);

                            foreach (JProperty property in propPlainTextJObj.Properties())
                            {
                                itemJObj[property.Name] = property.Value;
                            }
                        }
                    }

                    input.Dispose();
                }
            }

            JToken token = itemJObj[Constants.EncryptedInfo];

            if (token != null)
            {
                JProperty encryptionPropertiesJProp = itemJObj.Property(Constants.EncryptedInfo);
                JObject   encryptionPropertiesJObj  = null;
                if (encryptionPropertiesJProp != null && encryptionPropertiesJProp.Value != null && encryptionPropertiesJProp.Value.Type == JTokenType.Object)
                {
                    encryptionPropertiesJObj = (JObject)encryptionPropertiesJProp.Value;
                }

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

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

                JObject plainTextJObj = await PropertyEncryptionProcessor.DecryptContentAsync(
                    encryptionProperties,
                    encryptor,
                    diagnosticsContext,
                    cancellationToken);

                foreach (JProperty property in plainTextJObj.Properties())
                {
                    itemJObj.Add(property.Name, property.Value);
                }

                itemJObj.Remove(Constants.EncryptedInfo);
                input.Dispose();
            }

            return(EncryptionProcessor.BaseSerializer.ToStream(itemJObj));
        }