Example #1
0
        /// <summary>
        ///     Compares a given (plain text) password with the (already hashed) password that is inside the hashData object.
        /// </summary>
        /// <param name="givenPassword">Plain text password to compare with</param>
        /// <param name="hashData">
        ///     The <see cref="PasswordHashingData" /> object that contains salt size, current hashed password, etc. for use in the
        ///     comparison
        ///     of the two passwords
        /// </param>
        public CommandResult ComparePasswords(string givenPassword, PasswordHashingData hashData)
        {
            if (String.IsNullOrWhiteSpace(givenPassword) || String.IsNullOrWhiteSpace(hashData?.HashedPassword) ||
                String.IsNullOrWhiteSpace(hashData.Salt))
            {
                return(CommandResultFactory.Fail("The given data to compare passwords was invalid.", false));
            }

            var saltByteArray = hashData.Salt.ToHexBytes();

            // Run initial hash at an application level
            var appHashedPassword = GetAppLevelPasswordHash(givenPassword);

            // Take the output of the initial hashing and run it through proper hashing with key stretching
            var hashedPasswordResult =
                ComputePasswordAndSaltBytes(saltByteArray, appHashedPassword, hashData.NumberOfIterations)
                .Then(computedBytes =>
            {
                var hashedPassword = computedBytes.ToHexString();
                return(CommandResultFactory.Ok <string>(hashedPassword));
            });

            if (hashedPasswordResult.IsFailure)
            {
                return(CommandResultFactory.Fail(
                           $"Computing the hash for the given password was not successful due to the following:\n{hashedPasswordResult.Message}"));
            }

            return(hashedPasswordResult.Value == hashData.HashedPassword
                ? CommandResultFactory.Ok()
                : CommandResultFactory.Fail("Passwords did not match"));
        }
Example #2
0
        /// <summary>
        ///     Computes a hash for a given password and returns a <see cref="PasswordHashingData" /> object to hold the elements
        ///     that made up the
        ///     hashed password
        /// </summary>
        /// <param name="givenPassword"></param>
        public CommandResult <PasswordHashingData> HashPassword(string givenPassword)
        {
            if (String.IsNullOrWhiteSpace(givenPassword))
            {
                return(CommandResultFactory.Fail("The given password was null or empty", (PasswordHashingData)null));
            }

            var hashData = new PasswordHashingData();
            var rand     = new Random();

            // Set the hash data
            hashData.NumberOfIterations = rand.Next(MinIterationRange, MaxIterationRange);
            hashData.SaltSize           = rand.Next(MinSaltSize, MaxSaltSize);
            var saltByteArray = GetRandomSalt(hashData.SaltSize);

            hashData.Salt = saltByteArray.ToHexString();

            // Run initial hash at an application level
            var appHashedPassword = GetAppLevelPasswordHash(givenPassword);

            // Take the output of the initial hashing and run it through proper hashing with key stretching
            var hashedPasswordResult =
                ComputePasswordAndSaltBytes(saltByteArray, appHashedPassword, hashData.NumberOfIterations)
                .Then(computedBytes =>
            {
                var hashedPassword = computedBytes.ToHexString();
                return(CommandResultFactory.Ok <string>(hashedPassword));
            });

            if (hashedPasswordResult.IsFailure)
            {
                return(CommandResultFactory.Fail(hashedPasswordResult.Message, hashData));
            }
            hashData.HashedPassword = hashedPasswordResult.Value;
            return(CommandResultFactory.Ok(hashData));
        }