public static async Task <JObject> DecryptAsync( JObject document, Encryptor encryptor, CosmosDiagnosticsContext diagnosticsContext, CancellationToken cancellationToken) { Debug.Assert(document != null); Debug.Assert(encryptor != null); Debug.Assert(diagnosticsContext != null); if (!document.TryGetValue(Constants.EncryptedInfo, out JToken encryptedInfo)) { return(document); } EncryptionProperties encryptionProperties = JsonConvert.DeserializeObject <EncryptionProperties>(encryptedInfo.ToString()); JObject plainTextJObj = await EncryptionProcessor.DecryptContentAsync( encryptionProperties, encryptor, diagnosticsContext, cancellationToken); document.Remove(Constants.EncryptedInfo); foreach (JProperty property in plainTextJObj.Properties()) { document.Add(property.Name, property.Value); } return(document); }
/// <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, 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); } } 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 EncryptionProcessor.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)); }
public static async Task <(JObject, DecryptionContext)> DecryptAsync( JObject document, Encryptor encryptor, CosmosDiagnosticsContext diagnosticsContext, CancellationToken cancellationToken) { Debug.Assert(document != null); Debug.Assert(encryptor != null); Debug.Assert(diagnosticsContext != null); if (!document.TryGetValue(Constants.EncryptedInfo, out JToken encryptedInfo)) { return(document, null); } EncryptionProperties encryptionProperties = JsonConvert.DeserializeObject <EncryptionProperties>(encryptedInfo.ToString()); JObject plainTextJObj = await EncryptionProcessor.DecryptContentAsync( encryptionProperties, encryptor, diagnosticsContext, cancellationToken); document.Remove(Constants.EncryptedInfo); List <string> pathsDecrypted = new List <string>(); foreach (JProperty property in plainTextJObj.Properties()) { document.Add(property.Name, property.Value); pathsDecrypted.Add("/" + property.Name); } DecryptionInfo decryptionInfo = new DecryptionInfo( pathsDecrypted, encryptionProperties.DataEncryptionKeyId); DecryptionContext decryptionContext = new DecryptionContext( new List <DecryptionInfo>() { decryptionInfo }); return(document, decryptionContext); }