CryptRaw() private method

Perform the central hashing step in the bcrypt scheme.
Thrown when one or more arguments have unsupported or /// illegal values.
private CryptRaw ( byte inputBytes, byte saltBytes, int logRounds ) : byte[]
inputBytes byte The input byte array to hash.
saltBytes byte The salt byte array to hash with.
logRounds int The binary logarithm of the number of rounds of hashing to apply.
return byte[]
Beispiel #1
0
        /// <summary>
        /// Calculates the hash of the specified password.
        /// </summary>
        /// <param name="password">Password (1 - 72 bytes).</param>
        /// <param name="salt">Salt (16 bytes).</param>
        /// <param name="workLoad">Workload (4 - 31).</param>
        /// <returns>Hash.</returns>
        public static byte[] Crypt(byte[] password, byte[] salt, int workLoad)
        {
            if (password == null)
            {
                throw new ArgumentNullException("password");
            }
            if (salt == null)
            {
                throw new ArgumentNullException("salt");
            }
            if (password.Length < 1 || password.Length > 72)
            {
                throw new ArgumentOutOfRangeException("password", password, "Must be between 1 and 72 bytes long.");
            }
            if (salt.Length != 16)
            {
                throw new ArgumentOutOfRangeException("salt", salt, "Must be 16 bytes long.");
            }
            if (workLoad < 4 || workLoad > 31)
            {
                throw new ArgumentOutOfRangeException("workLoad", workLoad, "Must be between 4 and 31.");
            }

            var crypt = new BCrypt();

            return(crypt.CryptRaw(password, salt, workLoad));
        }
Beispiel #2
0
        /// <summary>
        /// Hash a password using the OpenBSD bcrypt scheme.
        /// </summary>
        /// <param name="password">The password to hash.</param>
        /// <param name="salt">The salt to hash with (perhaps generated
        /// using <c>BCrypt.GenerateSalt</c>).</param>
        /// <returns>The hashed password.</returns>
        public static string HashPassword(string password, string salt)
        {
            if (password == null)
            {
                throw new ArgumentNullException("password");
            }
            if (salt == null)
            {
                throw new ArgumentNullException("salt");
            }

            char minor = (char)0;

            if (salt[0] != '$' || salt[1] != '2')
            {
                throw new ArgumentException("Invalid salt version");
            }

            int offset;

            if (salt[1] != '$')
            {
                minor = salt[2];
                if (minor != 'a' || salt[3] != '$')
                {
                    throw new ArgumentException("Invalid salt revision");
                }
                offset = 4;
            }
            else
            {
                offset = 3;
            }

            // Extract number of rounds
            if (salt[offset + 2] > '$')
            {
                throw new ArgumentException("Missing salt rounds");
            }

            int rounds = Int32.Parse(salt.Substring(offset, 2), NumberFormatInfo.InvariantInfo);

            byte[] passwordBytes = Encoding.UTF8.GetBytes(password + (minor >= 'a' ? "\0" : String.Empty));
            byte[] saltBytes     = DecodeBase64(salt.Substring(offset + 3, 22),
                                                BCRYPT_SALT_LEN);

            BCrypt bcrypt = new BCrypt();

            byte[] hashed = bcrypt.CryptRaw(passwordBytes, saltBytes, rounds);

            StringBuilder rs = new StringBuilder();

            rs.Append("$2");
            if (minor >= 'a')
            {
                rs.Append(minor);
            }
            rs.Append('$');
            if (rounds < 10)
            {
                rs.Append('0');
            }
            rs.Append(rounds);
            rs.Append('$');
            rs.Append(EncodeBase64(saltBytes, saltBytes.Length));
            rs.Append(EncodeBase64(hashed,
                                   (bf_crypt_ciphertext.Length * 4) - 1));

            return(rs.ToString());
        }
Beispiel #3
0
        /// <summary>Hash a password using the OpenBSD bcrypt scheme.</summary>
        /// <exception cref="ArgumentException">Thrown when one or more arguments have unsupported or
        ///                                     illegal values.</exception>
        /// <param name="input">The password to hash.</param>
        /// <param name="salt">    the salt to hash with (perhaps generated using BCrypt.gensalt).</param>
        /// <returns>The hashed password</returns>
        public static string HashPassword(string input, string salt)
        {
            if (input == null)
            {
                throw new ArgumentNullException(nameof(input));
            }

            if (string.IsNullOrEmpty(salt))
            {
                throw new ArgumentException("Invalid salt", nameof(salt));
            }

            // Determinthe starting offset and validate the salt
            int startingOffset;
            var minor = (char)0;

            if (salt[0] != '$' || salt[1] != '2')
            {
                throw new SaltParseException("Invalid salt version");
            }
            if (salt[2] == '$')
            {
                startingOffset = 3;
            }
            else
            {
                minor = salt[2];
                if (!(minor == 'a' || minor == 'b' || minor == 'x' || minor == 'y') || salt[3] != '$')
                {
                    throw new SaltParseException("Invalid salt revision");
                }
                startingOffset = 4;
            }

            // Extract number of rounds
            if (salt[startingOffset + 2] > '$')
            {
                throw new SaltParseException("Missing salt rounds");
            }

            // Extract details from salt
            var logRounds     = Convert.ToInt32(salt.Substring(startingOffset, 2));
            var extractedSalt = salt.Substring(startingOffset + 3, 22);

            var inputBytes = Encoding.UTF8.GetBytes((input + (minor >= 'a' ? "\0" : "")));
            var saltBytes  = DecodeBase64(extractedSalt, BcryptSaltLen);

            var bCrypt = new BCrypt();
            var hashed = bCrypt.CryptRaw(inputBytes, saltBytes, logRounds);

            // Generate result string
            var result = new StringBuilder();

            result.Append("$2");
            if (minor >= 'a')
            {
                result.Append(minor);
            }
            result.AppendFormat("${0:00}$", logRounds);
            result.Append(EncodeBase64(saltBytes, saltBytes.Length));
            result.Append(EncodeBase64(hashed, (BfCryptCiphertext.Length * 4) - 1));
            return(result.ToString());
        }
Beispiel #4
0
        /// <summary>Hash a password using the OpenBSD BCrypt scheme.</summary>
        /// <exception cref="ArgumentException">Thrown when one or more arguments have unsupported or illegal values.</exception>
        /// <param name="inputKey">The password or string to hash.</param>
        /// <param name="salt">    the salt to hash with (best generated using BCrypt.gensalt).</param>
        /// <param name="enhancedEntropy">Set to true,the string will undergo SHA384 hashing to make use of available entropy prior to bcrypt hashing</param>
        /// <returns>The hashed password</returns>
        /// <exception cref="SaltParseException">Thrown when the <paramref name="salt"/> could not pe parsed.</exception>
        public static string HashPassword(string inputKey, string salt, bool enhancedEntropy)
        {
            if (inputKey == null)
            {
                throw new ArgumentNullException(nameof(inputKey));
            }

            if (string.IsNullOrEmpty(salt))
            {
                throw new ArgumentException("Invalid salt", nameof(salt));
            }

            // Determine the starting offset and validate the salt
            int  startingOffset;
            char minor = (char)0;

            if (salt[0] != '$' || salt[1] != '2')
            {
                throw new SaltParseException("Invalid salt version");
            }
            else if (salt[2] == '$')
            {
                startingOffset = 3;
            }
            else
            {
                minor = salt[2];
                if (minor != 'a' && minor != 'b' && minor != 'x' && minor != 'y' || salt[3] != '$')
                {
                    throw new SaltParseException("Invalid salt revision");
                }
                startingOffset = 4;
            }

            // Extract number of rounds
            if (salt[startingOffset + 2] > '$')
            {
                throw new SaltParseException("Missing salt rounds");
            }

            // Extract details from salt
            int workFactor = Convert.ToInt16(salt.Substring(startingOffset, 2));

            // Throw if log rounds are out of range on hash, deals with custom salts
            if (workFactor < 1 || workFactor > 31)
            {
                throw new SaltParseException("Salt rounds out of range");
            }

            string extractedSalt = salt.Substring(startingOffset + 3, 22);

            byte[] inputBytes = SafeUTF8.GetBytes(inputKey + (minor >= 'a' ? Nul : EmptyString));

            if (enhancedEntropy)
            {
                inputBytes = SHA384.Create().ComputeHash(inputBytes);
            }

            byte[] saltBytes = DecodeBase64(extractedSalt, BCryptSaltLen);

            BCrypt bCrypt = new BCrypt();

            byte[] hashed = bCrypt.CryptRaw(inputBytes, saltBytes, workFactor);

            // Generate result string
            StringBuilder result = new StringBuilder();

            result.AppendFormat("$2{1}${0:00}$", workFactor, minor);
            result.Append(EncodeBase64(saltBytes, saltBytes.Length));
            result.Append(EncodeBase64(hashed, (BfCryptCiphertext.Length * 4) - 1));

            return(result.ToString());
        }
Beispiel #5
0
        /// <summary>Hash a password using the OpenBSD bcrypt scheme.</summary>
        /// <exception cref="ArgumentException">Thrown when one or more arguments have unsupported or
        ///                                     illegal values.</exception>
        /// <param name="input">The password to hash.</param>
        /// <param name="salt">    the salt to hash with (perhaps generated using BCrypt.gensalt).</param>
        /// <returns>The hashed password</returns>
        public static string HashPassword(string input, string salt)
        {
            if (input == null)
                throw new ArgumentNullException("input");

            if (string.IsNullOrEmpty(salt))
                throw new ArgumentException("Invalid salt", "salt");

            // Determinthe starting offset and validate the salt
            int startingOffset;
            char minor = (char)0;
            if (salt[0] != '$' || salt[1] != '2')
                throw new SaltParseException("Invalid salt version");
            if (salt[2] == '$')
                startingOffset = 3;
            else
            {
                minor = salt[2];
                if (minor != 'a' || salt[3] != '$')
                    throw new SaltParseException("Invalid salt revision");
                startingOffset = 4;
            }

            // Extract number of rounds
            if (salt[startingOffset + 2] > '$')
                throw new SaltParseException("Missing salt rounds");

            // Extract details from salt
            int logRounds = Convert.ToInt32(salt.Substring(startingOffset, 2));
            string extractedSalt = salt.Substring(startingOffset + 3, 22);

            byte[] inputBytes = Encoding.UTF8.GetBytes((input + (minor >= 'a' ? "\0" : "")));
            byte[] saltBytes = DecodeBase64(extractedSalt, BCRYPT_SALT_LEN);

            BCrypt bCrypt = new BCrypt();
            byte[] hashed = bCrypt.CryptRaw(inputBytes, saltBytes, logRounds);

            // Generate result string
            StringBuilder result = new StringBuilder();
            result.Append("$2");
            if (minor >= 'a')
                result.Append(minor);
            result.AppendFormat("${0:00}$", logRounds);
            result.Append(EncodeBase64(saltBytes, saltBytes.Length));
            result.Append(EncodeBase64(hashed, (_BfCryptCiphertext.Length * 4) - 1));
            return result.ToString();
        }