/// <summary>
        /// <para>Encrypts a secret using the configured <c>SymmetricAlgorithm</c>.</para>
        /// </summary>
        /// <param name="plaintext"><para>The input to be encrypted. It is the responsibility of the caller to clear this
        /// byte array when finished.</para></param>
        /// <returns><para>The resulting cipher text.</para></returns>
        /// <seealso cref="ISymmetricCryptoProvider.Encrypt"/>
        public byte[] Encrypt(byte[] plaintext)
        {
            if (plaintext == null)
            {
                throw new ArgumentNullException("plainText");
            }
            if (plaintext.Length == 0)
            {
                throw new ArgumentException(Resources.ExceptionByteArrayValueMustBeGreaterThanZeroBytes, "plaintext");
            }

            byte[] output = null;

            try
            {
                using (SymmetricCryptographer crypto = new SymmetricCryptographer(algorithmType, key))
                {
                    output = crypto.Encrypt(plaintext);
                }
            }
            catch (Exception e)
            {
                InstrumentationProvider.FireCyptographicOperationFailed(Resources.EncryptionFailed, e);
                throw;
            }
            InstrumentationProvider.FireSymmetricEncryptionPerformed();

            return(output);
        }
        /// <summary>
        /// Computes the hash value of plain text.
        /// </summary>
        /// <param name="plaintext">The input for which to compute the hash.</param>
        /// <returns>The computed hash code.</returns>
        public byte[] CreateHash(byte[] plaintext)
        {
            byte[] hash = null;

            try
            {
                hash = CreateHashWithSalt(plaintext, null);
            }
            catch (Exception e)
            {
                InstrumentationProvider.FireCyptographicOperationFailed(Resources.HashCreationFailed, e);
                throw;
            }

            InstrumentationProvider.FireHashOperationPerformed();
            return(hash);
        }
        /// <summary>
        /// Compares plain text input with a computed hash.
        /// </summary>
        /// <param name="plaintext">The input for which you want to compare the hash to.</param>
        /// <param name="hashedtext">The hash value for which you want to compare the input to.</param>
        /// <returns><c>true</c> if plainText hashed is equal to the hashedText. Otherwise, <c>false</c>.</returns>
        public bool CompareHash(byte[] plaintext, byte[] hashedtext)
        {
            if (plaintext == null)
            {
                throw new ArgumentNullException("plainText");
            }
            if (hashedtext == null)
            {
                throw new ArgumentNullException("hashedText");
            }
            if (hashedtext.Length == 0)
            {
                throw new ArgumentException(Resources.ExceptionByteArrayValueMustBeGreaterThanZeroBytes, "hashedText");
            }

            bool result = false;

            byte[] hashedPlainText = null;
            byte[] salt            = null;
            try
            {
                try
                {
                    salt            = ExtractSalt(hashedtext);
                    hashedPlainText = CreateHashWithSalt(plaintext, salt);
                }
                finally
                {
                    CryptographyUtility.ZeroOutBytes(salt);
                }
                result = CryptographyUtility.CompareBytes(hashedPlainText, hashedtext);
            }
            catch (Exception e)
            {
                InstrumentationProvider.FireCyptographicOperationFailed(Resources.HashComparisonFailed, e);
                throw;
            }

            InstrumentationProvider.FireHashComparisonPerformed();
            if (!result)
            {
                InstrumentationProvider.FireHashMismatchDetected();
            }
            return(result);
        }