/// <inheritdoc />
        public Task <IMessageEncryptionService> CreateMessageEncryptionService(IConfiguration configuration)
        {
            IMessageEncryptionService messageEncryptionService = null;
            var enabled = configuration != null && configuration.GetValue("enabled", false);

            if (enabled)
            {
                var key = (HexEncodedSecurityKey)configuration.GetValue <string>("key");
                if (key == null)
                {
                    throw new ConfigurationErrorsException("Attribute 'key' is required for AES message encryption service");
                }

                var fallbackKeys = configuration.GetSection("fallbackKeys")
                                   .GetChildren()
                                   .Select(k => (HexEncodedSecurityKey)k.Value)
                                   .ToList();

                var aesOptions = new AesMessageEncryptionOptions(key)
                {
                    FallbackKeys = fallbackKeys
                };
                messageEncryptionService = new AesMessageEncryptionService(aesOptions);
            }
            return(Task.FromResult(messageEncryptionService));
        }
        /// <summary>
        /// Initializes a new <see cref="AesMessageEncryptionService"/> with the specified
        /// <paramref name="options"/>
        /// </summary>
        /// <param name="options">Options that influence the behavior of the AES message
        /// encryption service</param>
        public AesMessageEncryptionService(AesMessageEncryptionOptions options)
        {
            if (options == null)
            {
                throw new ArgumentNullException(nameof(options));
            }

            _diagnosticService = options.DiagnosticService;
#if NET452 || NET461
            _encryptionKey  = options.Key.GetSymmetricKey();
            _decryptionKeys = new[] { _encryptionKey }.Union(
                options.FallbackKeys?
                .Where(k => k != null)
                .Select(k => k.GetSymmetricKey())
                .ToList()
                ?? Enumerable.Empty <byte[]>())
            .ToList();
#endif
#if NETSTANDARD2_0
            _encryptionKey  = options.Key.Key;
            _decryptionKeys = new[] { _encryptionKey }.Union(
                options.FallbackKeys?
                .Where(k => k != null)
                .Select(k => k.Key)
                .ToList()
                ?? Enumerable.Empty <byte[]>())
            .ToList();
#endif
        }
        /// <inheritdoc />
        public Task <IMessageEncryptionService> CreateMessageEncryptionService(EncryptionElement configuration)
        {
            IMessageEncryptionService messageEncryptionService = null;
            var enabled = configuration.Enabled;

            if (enabled)
            {
                var key = (HexEncodedSecurityKey)configuration.Key;
                if (key == null)
                {
                    throw new ConfigurationErrorsException("Attribute 'key' is required for AES message encryption service");
                }

                var fallbackKeys = configuration.FallbackKeys.Select(k => (HexEncodedSecurityKey)k.Key).ToList();
                var aesOptions   = new AesMessageEncryptionOptions(key)
                {
                    FallbackKeys = fallbackKeys
                };
                messageEncryptionService = new AesMessageEncryptionService(aesOptions);
            }
            return(Task.FromResult(messageEncryptionService));
        }