protected void btn_submit_Click(object sender, EventArgs e) { // validate fields if (!Validate_Fields()) { return; } string email = tb_email.Text.Trim(); string password = tb_password.Text.Trim(); string input_fName = tb_fName.Text.Trim(); string input_lName = tb_lName.Text.Trim(); string input_ccCVV = tb_ccCVV.Text.Trim(); string newPassword = tb_newPassword.Text.Trim(); string confirmNewPassword = tb_confirmNewPassword.Text.Trim(); if (!UserUtils.Exist(email)) { showFeedback("Invalid email address."); return; } if (!UserUtils.Authenticate(email, password)) { showFeedback("Sorry, with the information you've provided. We still can't verify that you're the account owner."); return; } string userId = null; string firstName = null, lastName = null; string cipherText = null; string iv = null; string key = null; string existPassSalt = null; string existPassHash = null; using (SqlConnection con = new SqlConnection(ConfigurationManager.ConnectionStrings["MYDBConnection"].ConnectionString)) { using (SqlCommand cmd = new SqlCommand("SELECT * FROM [dbo].[Users] WHERE Email = @Email", con)) { cmd.CommandType = CommandType.Text; cmd.Parameters.AddWithValue("@Email", email); if (con.State == ConnectionState.Closed || con.State == ConnectionState.Broken) { con.Open(); } SqlDataReader sdr = cmd.ExecuteReader(); if (sdr.Read()) { userId = sdr["Id"].ToString(); firstName = sdr["FirstName"].ToString(); lastName = sdr["LastName"].ToString(); existPassSalt = sdr["PasswordSalt"].ToString(); existPassHash = sdr["PasswordHash"].ToString(); cipherText = sdr["CCCVV"].ToString(); iv = sdr["IV"].ToString(); key = sdr["Key"].ToString(); } } } string plainText = DataCrypt.Decrypt(cipherText, iv, key); if (!(plainText.Equals(input_ccCVV) && firstName.Equals(input_fName) && lastName.Equals(input_lName))) { showFeedback("Invalid details provided."); return; } if (Password.ComparePasswordHash(Password.GetPasswordHash(newPassword, existPassSalt), existPassHash)) { showFeedback("Your new password cannot be a password you've used before."); return; } Password.UpdatePassword(userId, Convert.ToBase64String(Password.GetPasswordHash(tb_newPassword.Text.Trim(), existPassSalt))); UserUtils.UnlockAccount(email); lbl_feedback.ForeColor = Color.Green; showFeedback("Password has been updated."); }
protected void Change_Password(object sender, EventArgs e) { // validate inputs if (!ValidateFields()) { return; } if (UserUtils.AccountAgeMinute(Session["Email"].ToString()) <= 5) { showFeedback("You have previously changed your password, you may reset again after 5 minutes after previous reset."); return; } string email = Session["email"].ToString(); string password = tb_curPassword.Text.Trim(); string newPassword = tb_newPassword.Text.Trim(); string pHash = null; string pSalt = null; string userId = null; string pHashNew = null; string queryString = "SELECT * FROM dbo.[Users] WHERE [Email] = @Email;"; using (SqlConnection connection = new SqlConnection(ConfigurationManager.ConnectionStrings["MYDBConnection"].ConnectionString)) { // Create the Command and Parameter objects. SqlCommand command = new SqlCommand(queryString, connection); command.Parameters.AddWithValue("@Email", email); // Open the connection in a try/catch block. // Create and execute the DataReader, writing the result // set to the console window. try { connection.Open(); SqlDataReader reader = command.ExecuteReader(); while (reader.Read()) { pHash = reader["PasswordHash"].ToString(); pSalt = reader["PasswordSalt"].ToString(); userId = reader["Id"].ToString(); } reader.Close(); } catch (Exception ex) { throw ex; } } // ensure if (pHash != null && pSalt != null) { // ensure authentication before authorizing if (Password.ComparePasswordHash(Password.GetPasswordHash(password, pSalt), pHash)) { // get string hash of the new password to check and change if there are no existance of it pHashNew = Convert.ToBase64String(Password.GetPasswordHash(newPassword, pSalt)); bool passwordHistory = false; // checks in password history if password has been used before // https://docs.microsoft.com/en-us/sql/t-sql/queries/select-order-by-clause-transact-sql?view=sql-server-ver15#a-specifying-integer-constants-for-offset-and-fetch-values string qStr = "SELECT [Hash] FROM [dbo].[PasswordHistory] WHERE UserId = @UserId and Hash = @Hash ORDER BY CreatedOn DESC OFFSET 0 ROW FETCH first 2 ROWS ONLY;"; using (SqlConnection con = new SqlConnection(ConfigurationManager.ConnectionStrings["MYDBConnection"].ConnectionString)) { using (SqlDataAdapter sda = new SqlDataAdapter(qStr, con)) { sda.SelectCommand.CommandType = CommandType.Text; sda.SelectCommand.Parameters.AddWithValue("@UserId", userId); sda.SelectCommand.Parameters.AddWithValue("@Hash", pHashNew); DataSet da = new DataSet(); sda.Fill(da); passwordHistory = (da.Tables[0].Rows.Count > 0); } } if (passwordHistory) { showFeedback("Previously 2 old passwords cannot be used."); return; } Password.UpdatePassword(userId, pHashNew); Password.SavePasswordHashToHistory(userId, pHash); showFeedback("Password has been updated."); lbl_feedback.ForeColor = Color.Green; } else { showFeedback("Current password is invalid, please try again."); return; } } }