BCrypt implementation.

BCrypt implements OpenBSD-style Blowfish password hashing using the scheme described in "A Future- Adaptable Password Scheme" by Niels Provos and David Mazieres.

This password hashing system tries to thwart off-line password cracking using a computationally-intensive hashing algorithm, based on Bruce Schneier's Blowfish cipher. The work factor of the algorithm is parameterised, so it can be increased as computers get faster.

Usage is really simple. To hash a password for the first time, call the method with a random salt, like this:

string pw_hash = BCrypt.HashPassword(plain_password);

To check whether a plaintext password matches one that has been hashed previously, use the Verify method:

if (BCrypt.Verify(candidate_password, stored_hash)) Console.WriteLine("It matches"); else Console.WriteLine("It does not match");

The GenerateSalt() method takes an optional parameter (workFactor) that determines the computational complexity of the hashing:

string strong_salt = BCrypt.GenerateSalt(10); string stronger_salt = BCrypt.GenerateSalt(12);

The amount of work increases exponentially (2^workFactor), so each increment is twice as much work. The default workFactor is 10, and the valid range is 4 to 31.

Esempio n. 1
0
        private void btnLogin_Click(object sender, RoutedEventArgs e)
        {
            var validate = context.Suppliers.Where(x => x.Email.Contains(txtEmail.Text)).SingleOrDefault();

            if (string.IsNullOrWhiteSpace(txtEmail.Text) || txtPass.Password.Equals(""))
            {
                MessageBox.Show("Email or Pass is must be filled");
            }
            //else if (!txtEmail.Text.All(char.IsLetterOrDigit))
            //{
            //    MessageBox.Show("*Name Must Contain Only number and text !");
            //}
            //else if (!IsValidEmailRegex(txtEmail.Text))
            else if (!Validate(txtEmail.Text))
            {
                MessageBox.Show("Invalid Email Address");
            }
            else if (validate == null)
            {
                MessageBox.Show("Email not available, you must be register");
            }
            else
            {
                //if (txtEmail.Text != validate.Email && txtPass.Text != validate.Pass)
                if (txtEmail.Text == validate.Email && Bcrypt.Verify(txtPass.Password, validate.Pass) == true)
                {
                    if (validate.Guid.Equals(""))
                    {
                        if (rememberMe.IsChecked == true)
                        {
                            Properties.Settings.Default.Mail     = txtEmail.Text;
                            Properties.Settings.Default.Password = txtPass.Password;
                            Properties.Settings.Default.Save();
                        }
                        MainWindow main = new MainWindow();
                        main.Show();
                    }
                    else
                    {
                        ChangePassWindow changePass = new ChangePassWindow();
                        changePass.getEmail.Text = txtEmail.Text;
                        changePass.Show();
                    }
                    this.Close();
                }
                else
                {
                    MessageBox.Show("Email or Pass is wrong");
                }
            }
        }
Esempio n. 2
0
        public async Task <User> AuthenticateAsync(string username, string password)
        {
            var user = await _dataContext.Users.SingleOrDefaultAsync(u => u.Username == username);

            if (user == null || !BC.Verify(password, user.Password))
            {
                throw new LogicException("Неправильный логин или пароль");
            }
            else
            {
                GenerateToken(user);
                return(user.WithoutPassword());
            }
        }
Esempio n. 3
0
        public async Task <User> RegisterAsync(string username, string password, string firstName, string lastName, string role)
        {
            var user = await _dataContext.Users.SingleOrDefaultAsync(u => u.Username == username);

            if (user != null)
            {
                throw new LogicException("Пользователь с указанным именем уже существует");
            }

            user = new User(username, BC.HashPassword(password), firstName, lastName, role);

            _dataContext.Users.Add(user);
            await _dataContext.SaveChangesAsync();

            GenerateToken(user);
            return(user.WithoutPassword());
        }
Esempio n. 4
0
 private void MaterialRaisedButton2_Click(object sender, EventArgs e)
 {
     try
     {
         if (txtLogin.Text == "" || txtPass.Text == "" || txtName.Text == "" || txtF.Text == "" || txtMail.Text == "" || txtPass2.Text == "")
         {
             MaterialMessageBox.Show("Пожалуйста заполните все поля", "Упс... Что-то пошло не так", MessageBoxButtons.OK);
         }
         else if (txtPass.Text != txtPass2.Text)
         {
             MaterialMessageBox.Show("Пароль не совпадают", "Упс... Что-то пошло не так", MessageBoxButtons.OK);
         }
         else
         {
             using (SqlConnection sqlcon = new SqlConnection(connectionString))
             {
                 sqlcon.Open();
                 SqlCommand sqlCmd = new SqlCommand("SotrAdd", sqlcon);
                 sqlCmd.CommandType = CommandType.StoredProcedure;
                 sqlCmd.Parameters.AddWithValue("Id_sotr", 0);
                 sqlCmd.Parameters.AddWithValue("Sost_sotr", "");
                 sqlCmd.Parameters.AddWithValue("I_sotr", txtName.Text.Trim());
                 sqlCmd.Parameters.AddWithValue("F_sotr", txtF.Text.Trim());
                 sqlCmd.Parameters.AddWithValue("O_sotr", txtO.Text.Trim());
                 sqlCmd.Parameters.AddWithValue("Mail_sotr", txtMail.Text.Trim());
                 sqlCmd.Parameters.AddWithValue("Staj_sotr", txtStaj.Text.Trim());
                 sqlCmd.Parameters.AddWithValue("Login_sotr", txtLogin.Text.Trim());
                 string CPass = Bcrypt.HashPassword(txtPass.Text, "$2a$11$fhmmGItQBp5ncDeCSnDPG/");
                 sqlCmd.Parameters.AddWithValue("Password_sotr", CPass);
                 sqlCmd.ExecuteNonQuery();
                 sqlcon.Close();
                 MaterialMessageBox.Show("Регистрация прошла успешно", "Поздравляем", MessageBoxButtons.OK);
                 Clear();
                 Auth auth = new Auth();
                 this.Hide();
                 auth.Show();
             }
         }
     }
     catch (Exception ex)
     {
         MaterialMessageBox.Show(ex.Message, "Что-то пошло не так", MessageBoxButtons.OK);
     }
 }
        public AccountResponse Create(CreateRequest model)
        {
            if (_context.Accounts.Any(x => x.Email == model.Email))
            {
                throw new AppException($"Email '{model.Email}' is already registered");
            }

            var account = _mapper.Map <Account>(model);

            account.Created  = DateTime.UtcNow;
            account.Verified = DateTime.UtcNow;

            account.PasswordHash = BC.HashPassword(model.Password);

            _context.Accounts.Add(account);
            _context.SaveChanges();

            return(_mapper.Map <AccountResponse>(account));
        }
        public void ResetPassword(ResetPasswordRequest model)
        {
            var account = _context.Accounts.SingleOrDefault(x =>
                                                            x.ResetToken == model.Token &&
                                                            x.ResetTokenExpires > DateTime.UtcNow);

            if (account == null)
            {
                throw new AppException("Invalid token");
            }

            account.PasswordHash      = BC.HashPassword(model.Password);
            account.PasswordReset     = DateTime.UtcNow;
            account.ResetToken        = null;
            account.ResetTokenExpires = null;

            _context.Accounts.Update(account);
            _context.SaveChanges();
        }
Esempio n. 7
0
        private void btnLogin_Click(object sender, EventArgs e)
        {
            SqlConnection  sqlcon = new SqlConnection(@"Data Source=MAHNO;Initial Catalog=PlanBadmin;" + "Integrated Security=true;");
            string         CPass  = Bcrypt.HashPassword(txtPassword.Text, "$2a$11$fhmmGItQBp5ncDeCSnDPG/");
            string         query  = "Select * from Admin Where Login ='******' and Password = '******'";
            SqlDataAdapter sda    = new SqlDataAdapter(query, sqlcon);
            DataTable      dtbl   = new DataTable();

            sda.Fill(dtbl);
            if (dtbl.Rows.Count == 1)
            {
                Main main = new Main();
                this.Hide();
                main.Show();
            }
            else
            {
                MessageBox.Show("Перепроверьте введеный вами логин и пароль");
            }
        }
        public AccountResponse Update(int id, UpdateRequest model)
        {
            var account = getAccount(id);

            if (account.Email != model.Email && _context.Accounts.Any(x => x.Email == model.Email))
            {
                throw new AppException($"Email '{model.Email}' is already taken");
            }

            if (!string.IsNullOrEmpty(model.Password))
            {
                account.PasswordHash = BC.HashPassword(model.Password);
            }
            _mapper.Map(model, account);
            account.Updated = DateTime.UtcNow;
            _context.Accounts.Update(account);
            _context.SaveChanges();

            return(_mapper.Map <AccountResponse>(account));
        }
Esempio n. 9
0
    public async Task <Response <string> > ResetPasswordAsync(ResetPasswordRequest request)
    {
        var user = await _userRepository.FindAsync(x =>
                                                   x.ResetToken == request.Token &&
                                                   x.ResetTokenExpires > DateTime.UtcNow);

        if (user == null)
        {
            throw new ApiException("Invalid token");
        }

        // update password and remove reset token
        user.Password          = BC.HashPassword(request.Password);
        user.PasswordReset     = DateTime.UtcNow;
        user.ResetToken        = null;
        user.ResetTokenExpires = null;

        await _userRepository.UpdateAsync(user);

        return(new Response <string>(user.Email, "Password Resetted."));
    }
        public void Register(RegisterRequest model, string origin)
        {
            if (_context.Accounts.Any(x => x.Email == model.Email))
            {
                sendAlreadyRegisteredEmail(model.Email, origin);
                return;
            }

            var account = _mapper.Map <Account>(model);

            var isFirstAccount = _context.Accounts.Count() == 0;

            account.Created           = DateTime.UtcNow;
            account.VerificationToken = randomTokenString();

            account.PasswordHash = BC.HashPassword(model.Password);

            _context.Accounts.Add(account);
            _context.SaveChanges();

            sendVerificationEmail(account, origin);
        }
Esempio n. 11
0
        //Обработка кнопки "Войти"
        private void BtnLogin_Click_1(object sender, EventArgs e)
        {
            try
            {
                LogUser = txtLogin.Text.Trim();
                sqlcon.Open();
                string         CPass       = Bcrypt.HashPassword(txtPassword.Text, "$2a$11$fhmmGItQBp5ncDeCSnDPG/");
                string         query       = "SELECT * FROM Sotr WHERE Login_sotr = '" + txtLogin.Text.Trim() + "' and Password_sotr = '" + CPass.Remove(50, 10) + "'";
                SqlDataAdapter sda         = new SqlDataAdapter(query, sqlcon);
                DbConnector    dbConnector = new DbConnector();
                SqlCommand     sqlCommand  = new SqlCommand("SELECT Id_sotr FROM dbo.Sotr where Login_sotr = 'zzzador4'", sqlcon);

                DataTable dtbl = new DataTable();
                sda.Fill(dtbl);
                if (dtbl.Rows.Count == 1)
                {
                    Program.IsAdmin = txtLogin.Text.Trim();
                    Main main = new Main();
                    Program.UserId = (int)sqlCommand.ExecuteScalar();
                    this.Hide();
                    main.Show();
                }
                else
                {
                    MaterialMessageBox.Show("Перепроверьте введенный вами логин и пароль", "Упс... Что-то пошло не так", MessageBoxButtons.OK);
                }
            }

            catch (Exception ex)
            {
                MessageBox.Show(ex.Message);
            }
            finally
            {
                sqlcon.Close();
            }
        }
Esempio n. 12
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());
        }
Esempio n. 13
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());
        }
Esempio n. 14
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());
        }
Esempio n. 15
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();
        }