public static async Task <TValue> Decrypt <TValue>(byte[] privateKey, EncryptedDataBlock dataBlock)
        {
            if (dataBlock == null)
            {
                throw new ArgumentNullException(nameof(dataBlock));
            }

            ValidateDigitalSignature(privateKey, dataBlock);

            var decryptedValue = await SymmetricallyDecrypt(Convert.FromBase64String(dataBlock.AesKey),
                                                            Convert.FromBase64String(dataBlock.InitialisationVector), dataBlock.EncryptedData)
                                 .ConfigureAwait(false);

            return(JsonConvert.DeserializeObject <TValue>(decryptedValue));
        }
        private static void ValidateDigitalSignature(byte[] privateKey, EncryptedDataBlock dataBlock)
        {
            try
            {
                var decryptedDigitalSignature =
                    Convert.ToBase64String(AsymmetricallyDecrypt(privateKey, dataBlock.DigitalSignature));
                var hash = Convert.ToBase64String(GenerateHash(Encoding.UTF8.GetBytes(dataBlock.EncryptedData)));

                if (string.Compare(decryptedDigitalSignature, hash, StringComparison.OrdinalIgnoreCase) != 0)
                {
                    throw new InvalidOperationException(
                              "The computed digital signature for the data block does not match the original digital signature.");
                }
            }
            catch (CryptographicException ex)
            {
                throw new InvalidOperationException(
                          "There was a problem decrypting the data block. Potential data corruption or packet tampering has occurred.",
                          ex);
            }
        }