public AesHmacCryptoService(CryptoConfiguration config, ISerializationProvider serializationProvider)
        {
            if (serializationProvider == null)
            {
                throw new ArgumentNullException(nameof(serializationProvider));
            }
            if (!IsCryptoConfigurationValid(config))
            {
                throw new ArgumentException("All configuration properties must be valid.", nameof(config));
            }
            SerializationProvider = serializationProvider;

            _lazyDerivedBytes = new Lazy <KeySaltPair>(() => GenerateDerivedBytes(config));
        }
        private static KeySaltPair GenerateDerivedBytes(CryptoConfiguration config)
        {
            var saltBytes       = new byte[SaltSize];
            var charSizeInBytes = sizeof(char);
            var characterCount  = Math.Min(SaltSize / charSizeInBytes, config.InitializationVector.Length);

            Encoding.UTF8.GetBytes(config.InitializationVector, 0, characterCount, saltBytes, 0);

            using (var derivePassword = new Rfc2898DeriveBytes(config.SecretKey, saltBytes))
            {
                using (var deriveDigest = new Rfc2898DeriveBytes(config.DigestKey, saltBytes))
                {
                    return(new KeySaltPair
                    {
                        SymmetricKey = derivePassword.GetBytes(KeySize),
                        Salt = derivePassword.Salt,
                        HashKey = deriveDigest.GetBytes(KeySize)
                    });
                }
            }
        }
 private static bool IsCryptoConfigurationValid(CryptoConfiguration config)
 {
     return(!string.IsNullOrEmpty(config.DigestKey) &&
            !string.IsNullOrEmpty(config.InitializationVector) &&
            !string.IsNullOrEmpty(config.SecretKey));
 }