So I'm making a login form in WPF. What I want to happen is that if I add a new user to my database the password gets hashed and stored in my database. This is not working and I don't know what I'm doing wrong. it's not even adding a new user without a hashed password. I would appreciate some help.
Click event to add a new user :
private void btnAdd_Click(object sender, RoutedEventArgs e)
{
clsDB cdb = new clsDB();
cdb.Adduser(tbUsername.Text, tbPassword.Text);
MessageBox.Show("user toegevoegd!");
this.Close();
}
this is the database class :
class clsDB
{
MySqlConnection conn = new MySqlConnection("server=localhost;Database=loginbcrypt;Uid=root;pwd=");
public int GetUserid(string un, string pwd)
{
int iUserID = 0;
conn.Open();
MySqlCommand cmd = conn.CreateCommand();
cmd.CommandText = "select UserId from users where Username = #username and Password = #password";
cmd.Parameters.AddWithValue("#username", un);
cmd.Parameters.AddWithValue("#password", pwd);
string sUserId = cmd.ExecuteScalar().ToString();
iUserID = int.Parse(sUserId);
conn.Close();
return iUserID;
}
public void Adduser(string un, string pwd)
{
try
{
conn.Open();
pwd = pwd + "$Y.N3T~J";
string salt = BCrypt.Net.BCrypt.GenerateSalt();
string hashToStoreInDatabase = BCrypt.Net.BCrypt.HashPassword(pwd, salt);
bool doesPasswordMatch = BCrypt.Net.BCrypt.Verify(pwd, un);
MySqlCommand cmd = conn.CreateCommand();
cmd.CommandText = "insert into users (Username, Password) values (#username, #password)";
cmd.Parameters.AddWithValue("#username", un);
cmd.Parameters.AddWithValue("#password", pwd);
cmd.ExecuteNonQuery();
}
catch (Exception)
{
}
finally
{
conn.Close();
}
}
}
Related
I have
Admin Side and Client-Side
and I have only one table for admin login and client login see the Reference Image
When User Login Then Insert an Entry as a User?
Reference:
https://imgur.com/a/PDoVSi9
I want to ex:
Database Entry
UserType: User
EmailId: benssok#gmail.com
Password: bens1234
FirstName: nicks
LastName: andrew
Code:
c#
Registation ClientSide:
protected void Button1_Click(object sender, EventArgs e)
{
string firstname = txtFirstName.Text;
string lastname = txtLastName.Text;
string emailid = txtEmailId.Text;
string password = txtclientpassword.Text;
ClientLogin_Click(firstname, lastname, emailid, password);
}`enter code here`
void ClientLogin_Click(string firstname,string lastname,string emailid,string Password)
{
string conn = ConfigurationManager.ConnectionStrings["connstr"].ToString();
SqlConnection cn = new SqlConnection(conn);
string Insertquery = "Insert into tbladminclient(FirstName,LastName,EmailId,Password) values(#FirstName,#LastName,#EmailId,#Password)";
SqlCommand cmd = new SqlCommand(Insertquery, cn);
cmd.CommandType = CommandType.Text;
cmd.Parameters.AddWithValue("#FirstName", firstname);
cmd.Parameters.AddWithValue("#LastName", lastname);
cmd.Parameters.AddWithValue("#EmailId", emailid);
cmd.Parameters.AddWithValue("#Password", Password);
try
{
cn.Open();
int validateOperation = cmd.ExecuteNonQuery();
if (validateOperation > 0)
{
Response.Write("successfully Registration");
Response.Redirect("ClientLogin.aspx");
}
else
{
Response.Write("Not successfully Registration");
}
}
catch (SqlException e)
{
Response.Write("error");
}
finally
{
cn.Close();
}
}
AdminLogin Page //Problem Occured when Same Login(AdminSide) and sameLogin(ClientSide) what the differance? How to resolve this problem ? How to Identify User(clientside) and admin(adminside)Login??
protected void Button1_Click(object sender, EventArgs e)
{
string userName = txtEmailId.Text;
string Password = txtUserPassword.Text;
Login_Click(userName, Password);
}
void Login_Click(string emailid, string Password)
{
string conn = ConfigurationManager.ConnectionStrings["connstr"].ToString();
SqlConnection cn = new SqlConnection(conn);
SqlCommand cmd = new SqlCommand("select * from tbladminclient where EmailId=#EmailId and Password=#Password", cn);
cn.Open();
cmd.Parameters.AddWithValue("#EmailId", emailid);
cmd.Parameters.AddWithValue("#Password", Password);
SqlDataReader dr = cmd.ExecuteReader(); //data read from the database
if (dr.HasRows == true) //HasRows means one or more row read from the database
{
Response.Write("successfully Login");
}
else
{
Response.Write("Not successfully Login");
}
cn.Close();
}
problem is when Same Login(AdminSide) and sameLogin(ClientSide) what the differance? How to resolve this problem ? How to Identify User(clientside) and admin(adminside)Login??
First when user(client-side) registration form fill up go to database and execute query
ALTER TABLE [tbladminclient]
ADD CONSTRAINT df_UserType
DEFAULT 'User' FOR UserType; //whenever you insert then Bydefault Entry is User:
how to identify user is client or admin
Code:
User LogIn
protected void Button1_Click(object sender, EventArgs e)
{
string emailid = txtemailId.Text;
string password = txtPassword.Text;
Client_Login(emailid,password);
}
void Client_Login(string emailid,string password)
{
string conn = ConfigurationManager.ConnectionStrings["connstr"].ToString();
SqlConnection cn = new SqlConnection(conn);
SqlCommand cmd = new SqlCommand("select * from tbladminclient where EmailId=#EmailId and Password=#Password", cn);
cn.Open();
cmd.Parameters.AddWithValue("#EmailId", emailid);
cmd.Parameters.AddWithValue("#Password", password);
SqlDataReader dr = cmd.ExecuteReader(); //data read from the database
if (dr.HasRows == true)//HasRows means one or more row read from the database
{
if (dr.Read())
{
if (dr["UserType"].ToString() == "User")
{
Response.Write("successfully Client Login");
}
else
{
Response.Write("Not successfully Client Login");
}
}
}
else
{
Response.Write("Not Found");
}
cn.Close();
}
Admin LogIn
protected void Button1_Click(object sender, EventArgs e)
{
string userName = txtEmailId.Text;
string Password = txtUserPassword.Text;
Login_Click(userName, Password);
}
void Login_Click(string emailid, string Password/*string UserType*/)
{
string conn = ConfigurationManager.ConnectionStrings["connstr"].ToString();
SqlConnection cn = new SqlConnection(conn);
SqlCommand cmd = new SqlCommand("select * from tbladminclient where EmailId=#EmailId and Password=#Password", cn);
cn.Open();
cmd.Parameters.AddWithValue("#EmailId", emailid);
cmd.Parameters.AddWithValue("#Password", Password);
SqlDataReader dr = cmd.ExecuteReader(); //data read from the database
if (dr.HasRows == true)//HasRows means one or more row read from the database
{
if (dr.Read())
{
if (dr["UserType"].ToString() == "admin")
{
Response.Write("Successfully Admin Login");
}
else
{
Response.Write("Not successfully Admin Login");
}
}
}
else
{
Response.Write("Not Found");
}
cn.Close();
}
I can't find my problem. Can anyone help me to check it. I'm new in C#.
public void Btnchange_Click(object sender, EventArgs args)
MySqlConnection con = new MySqlConnection("server=localhost;user id=root;persistsecurityinfo=True;database=user;password=1234");
MySqlDataAdapter sda = new MySqlDataAdapter("select Password from user.register where Password='" + textoldpassword.Text + "'", con);
DataTable dt = new DataTable();
sda.Fill(dt);
if (dt.Rows.Count.ToString() == "1")
{
if (textnewpassword.Text == textconfirmpassword.Text)
{
con.Open();
MySqlCommand cmd = new MySqlCommand("update user.register set Password ='" + textconfirmpassword.Text + "' where Password ='" + textoldpassword.Text + "'", con);
cmd.ExecuteNonQuery();
con.Close();
lblmsg.Text = "Succesfully Updated";
lblmsg.ForeColor = Color.Green;
}
else
{
lblmsg.Text = "New password and confirm password should be same!";
}
I expect it can update and change my password.
There are many many (mostly) minor mistakes in your code:
use some kind of Id fields in your sql tables
never do an update like you did (update the field WHERE this field is equals to...)
create your own class and bind the query result to this class
when a class implements IDisposable interface, always use the keyword 'using'
never ever user string concatenation in sql queries!!! SQL INJECTION!!! always use parametrized sql queries
Here's a simple example for your form. Let's suppose your
user.register table has the following columns:
- Id
- Username
- Password
Now let's create your own class (maybe right under your button click
event, so it can be private this time):
private class MyUser
{
public int Id { get; set; }
public string Username { get; set; }
public string Password { get; set; }
}
Then your button click event should look like this:
private void Btnchange_Click(object sender, EventArgs e) {
if (!textnewpassword.Text.Trim().Equals(textconfirmpassword.Text.Trim()))
{
throw new ArgumentException("New password and confirm password should be same!");
}
List<MyUser> myUsers = new List<MyUser>();
using (MySqlConnection con =
new MySqlConnection(
"server=localhost;user id=root;persistsecurityinfo=True;database=user;password=1234"))
{
using (MySqlCommand cmd = new MySqlCommand("select * from user.register where Username=#user and Password=#pass", con))
{
cmd.Parameters.AddWithValue("#user", textusername.Text.Trim());
cmd.Parameters.AddWithValue("#pass", textoldpassword.Text.Trim());
if (cmd.Connection.State != ConnectionState.Open) cmd.Connection.Open();
using (MySqlDataReader dr = cmd.ExecuteReader())
{
while (dr.Read())
{
myUsers.Add(new MyUser
{
Id = (int)dr["Id"],
Username = dr["Username"].ToString(),
Password = dr["Password"].ToString()
});
}
}
if (cmd.Connection.State == ConnectionState.Open) cmd.Connection.Close();
}
if (!myUsers.Any())
{
throw new ArgumentException("No users found with the given username/password pair!");
}
if (myUsers.Count != 1)
{
throw new ArgumentException("More than 1 user has the same username and password in the database!");
}
MyUser user = myUsers.First();
user.Password = textnewpassword.Text.Trim();
using (MySqlCommand cmd = new MySqlCommand("update user.register set Password=#pass where Id=#id"))
{
cmd.Parameters.AddWithValue("#pass", user.Password);
cmd.Parameters.AddWithValue("#id", user.Id);
if (cmd.Connection.State != ConnectionState.Open) cmd.Connection.Open();
cmd.ExecuteNonQuery();
if (cmd.Connection.State == ConnectionState.Open) cmd.Connection.Close();
}
} }
...and so on.
I have hased my password right there on in the registration.aspx. having this code in my business layer:
public static string CreateSHAHash(string Phrase)
{
SHA512Managed HashTool = new SHA512Managed();
Byte[] PhraseAsByte = System.Text.Encoding.UTF8.GetBytes(string.Concat(Phrase));
Byte[] EncryptedBytes = HashTool.ComputeHash(PhraseAsByte);
HashTool.Clear();
return Convert.ToBase64String(EncryptedBytes);
}
and this code in the register page:
scm.Parameters.AddWithValue("#Password", BusinessLayer.ShoppingCart.CreateSHAHash(txtPW.Text));
Having the codes above, the password are being hashed in the DB and it is working fine when I log in with this code:
protected void btn_Login_Click(object sender, EventArgs e)
{
SqlConnection conn = new SqlConnection(ConfigurationManager.ConnectionStrings["RegistrationConnectionString"].ConnectionString);
conn.Open();
string checkuser = "select count(*) from UserData where Username = '" + txtUser.Text + "'";
SqlCommand scm = new SqlCommand(checkuser, conn);
int temp = Convert.ToInt32(scm.ExecuteScalar().ToString());
conn.Close();
if (temp == 1)
{
conn.Open();
string checkPassword = "select Password from UserData where Username ='" + txtUser.Text + "'";
SqlCommand passCom = new SqlCommand(checkPassword, conn);
string password = passCom.ExecuteScalar().ToString();
if (password == BusinessLayer.ShoppingCart.CreateSHAHash(txtPassword.Text))
{
Session["New"] = txtUser.Text;
Response.Write("<script>alert('Logged In')</script>");
Response.Redirect("OrderNow.aspx");
}
else
{
lblcrederror.Text = ("Credentials dont match");
}
}
else
{
lblcrederror.Text = ("Credentials dont match");
}
However when I change it having this code in my changepassword.aspx, its not letting me in with my new password.
protected void btn_update_Click(object sender, EventArgs e)
{
SqlConnection con = new SqlConnection(conn);
con.Open();
str = "select * from UserData ";
com = new SqlCommand(str, con);
SqlDataReader reader = com.ExecuteReader();
while (reader.Read())
{
if (BusinessLayer.ShoppingCart.CreateSHAHash(txt_cpassword.Text) == reader["Password"].ToString())
{
up = 1;
}
}
reader.Close();
con.Close();
if (up == 1)
{
con.Open();
str = "update UserData set Password=#Password where UserName='" + Session["New"].ToString() + "'";
com = new SqlCommand(str, con);
com.Parameters.Add(new SqlParameter("#Password", SqlDbType.VarChar, 50));
com.Parameters["#Password"].Value = BusinessLayer.ShoppingCart.CreateSHAHash(txt_npassword.Text);
com.ExecuteNonQuery();
con.Close();
lbl_msg.Text = "Password changed Successfully";
}
else
{
lbl_msg.Text = "Please enter correct Current password";
}
}
What am I missing here?
Check if the 50 truncates the hash.
com.Parameters.Add(new SqlParameter("#Password", SqlDbType.VarChar, 50));
On a sidenote i see that your solution is very open to SQL injection.
"select Password from UserData where Username ='" + txtUser.Text + "'";
A user can write sql statements in the textbox, and hijack your database, create his own tables or drop the whole database. You should always parameterize the queries. I see that you did that to the Update statement, but you should consider doing it for all of your variables.
This quickly creates a lot of code, so i would also consider making an SQL wrapper, that wraps in all of the things you repeat. When you are done refactoring it could look something like this:
var sql = new SqlWrapper("select Password from UserData where Username = #username", txtUser.Text);
var dataSet = sql.Execute();
Then you can hide all of your connectionstring, commands++ behind this wrapper and only tell the wrapper what you actually care about.
You should also consider using a salt for your password. If you and I have the same password, the hash will be the same. A salt will fix this problem.
A good article about password security -> https://crackstation.net/hashing-security.htm
I am trying to log on with a username and original password that already stored in the database with a hashed password.
But, when I am trying to log on, I received the message says that value cannot be null on if (salt == null) {
throw new ArgumentNullException("salt");
}
I am using BCrypt.cs for hashing the password in the database. BCrypt.cs
Here is my code for register the user:
string connectionString = #"Provider=Microsoft.ACE.OLEDB.12.0;Data Source=..\db1.accdb";
Password.Hashed = BCrypt.HashPassword(this.textBox2.Text, BCrypt.GenerateSalt(12));
using (OleDbConnection conn = new OleDbConnection(connectionString))
{
string query = "INSERT INTO [Member] ([Username], [Password], [UserType]) VALUES (#Username, #Password, #UserType)";
conn.Open();
using (OleDbCommand cmd = new OleDbCommand(query, conn))
{
cmd.Parameters.Add("#Username", System.Data.OleDb.OleDbType.VarChar);
cmd.Parameters["#Username"].Value = this.textBox1.Text;
cmd.Parameters.Add("#Password", System.Data.OleDb.OleDbType.VarChar);
cmd.Parameters["#Password"].Value = Password.Hashed;
cmd.Parameters.Add("#UserType", System.Data.OleDb.OleDbType.VarChar);
cmd.Parameters["#UserType"].Value = this.comboBox1.SelectedItem;
cmd.ExecuteNonQuery();
System.Media.SoundPlayer _sound = new System.Media.SoundPlayer(#"C:\Windows\Media\Windows Exclamation.wav");
_sound.Play();
DialogResult _dialogResult = MessageBox.Show("Added Successfully!", "Success", MessageBoxButtons.OK);
if (_dialogResult == DialogResult.OK)
{
this.Hide();
Login _login = new Login();
_login.ShowDialog();
this.Close();
}
}
conn.Close();
}
Here is my code for log on the user:
string connectionString = #"Provider=Microsoft.ACE.OLEDB.12.0;Data Source=..\db1.accdb";
using (OleDbConnection conn = new OleDbConnection(connectionString))
{
string query = "SELECT [Username], [Password], [UserType] FROM [Member] WHERE [Username] = #Username AND [Password] = #Password";
conn.Open();
using (OleDbCommand cmd = new OleDbCommand(query, conn))
{
cmd.Parameters.Add("#Username", System.Data.OleDb.OleDbType.VarChar);
cmd.Parameters["#Username"].Value = this.textBox1.Text;
cmd.Parameters.Add("#Password", System.Data.OleDb.OleDbType.VarChar);
cmd.Parameters["#Password"].Value = BCrypt.CheckPassword(this.textBox2.Text, Password.Hashed);
using (OleDbDataReader dReader = cmd.ExecuteReader())
{
if (dReader.Read())
{
UserInformation.CurrentLoggedInUser = (string)dReader["Username"];
UserInformation.CurrentLoggedInUserType = (string)dReader["UserType"];
this.Hide();
this.Close();
}
else
{
Validation(sender, e);
RecursiveClearTextBoxes(this.Controls);
}
dReader.Close();
conn.Close();
}
}
}
Here is the password class:
public static string Hashed
{
get;
set;
}
Any help would be appreciated and your answer much appreciated!
Thank you so much.
EDITED:
My database looks like this:
That password was hashed (salt) and my original password that I use for the login is Kaoru. That password was generated from original password, which is Kaoru
Try the following code:
string connectionString = #"Provider=Microsoft.ACE.OLEDB.12.0;Data Source=..\db1.accdb";
using (OleDbConnection conn = new OleDbConnection(connectionString))
{
string query = "SELECT [Username], [Password], [UserType] FROM [Member] WHERE [Username] = #Username";
conn.Open();
using (OleDbCommand cmd = new OleDbCommand(query, conn))
{
cmd.Parameters.Add("#Username", System.Data.OleDb.OleDbType.VarChar);
cmd.Parameters["#Username"].Value = this.textBox1.Text;
using (OleDbDataReader dReader = cmd.ExecuteReader())
{
bool isValidPassword = false;
if (dReader.Read())
{
string password = (string)dReader["Password"];
bool isValidPassword = BCrypt.CheckPassword(this.textBox2.Text, password);
if (isValidPassword)
{
UserInformation.CurrentLoggedInUser = (string)dReader["Username"];
UserInformation.CurrentLoggedInUserType = (string)dReader["UserType"];
this.Hide();
this.Close();
}
}
if (!isValidPassword)
{
Validation(sender, e);
RecursiveClearTextBoxes(this.Controls);
}
}
}
}
I have one table called Users, which have 4 columns
UserId
UserName
Password
Role
If login is successful, I want to know the UserId and Role values ,
for login validate I wrote following function,
private bool ValidationFunction(string username, string pwd)
{
bool boolReturnValue = false;
string s = "correct connection string";
SqlConnection con = new SqlConnection(s);
con.Open();
string sqlUserName;
sqlUserName = "SELECT UserName,Password FROM Users WHERE UserName ='" + username + "' AND Password ='" + pwd + "'";
SqlCommand cmd = new SqlCommand(sqlUserName, con);
string CurrentName;
CurrentName = (string)cmd.ExecuteScalar();
if (CurrentName != null)
{
boolReturnValue = true;
}
else
{
Session["UserName"] = "";
boolReturnValue = false;
}
return boolReturnValue;
}
ExecuteScalar() function returns only the top record value of the first column. So you need to use ExecuteReader() instead.
Other important thing is you better use a parameterised query to pass those user typed values into the database. You are open for sql injection attacks this way.
Try this:
using (SqlConnection cnn = new SqlConnection("yourConnectionString"))
{
string sql= "select userId,role from users " +
"where username=#uName and password=#pWord";
using (SqlCommand cmd = new SqlCommand(sql,cnn))
{
cmd.Parameters.AddWithValue("#uName", username);
cmd.Parameters.AddWithValue("#pWord", pwd);
cnn.Open();
SqlDataReader reader = cmd.ExecuteReader();
while (reader.Read())
{
//get the reader values here.
}
}
}
If UserID and Role are in the Users table, you can use the code below. It has the added benefit of protection from SQL injection attacks using parameters.
private class User
{
public int UserID {get;set;}
public string Role {get;set;}
public string UserName {get;set;}
}
private bool ValidationFunction(string username, string pwd, out User)
{
bool boolReturnValue = false;
string s = "correct connection string";
SqlConnection con = new SqlConnection(s);
con.Open();
string sqlUserName;
sqlUserName = "SELECT UserName,Password,UserID,Role FROM Users WHERE UserName =#usr AND Password=#pwd";
SqlCommand cmd = new SqlCommand(sqlUserName, con);
cmd.Parameters.Add(new SqlParameter("usr", username));
cmd.Parameters.Add(new SqlParameter("pwd", pwd));
SqlDataReader reader = command.ExecuteReader();
if (reader.Read())
{
boolReturnValue = true;
User = new User(){UserName = username, UserID=reader.GetInt32(2), Role=reader.GetString(3)};
}
else
{
Session["UserName"] = "";
boolReturnValue = false;
}
return boolReturnValue;
}
Use query
SqlDataReaer reader= Select *from Users where password="yourPassword"
and then you can get whatever you want i.e. reader["userName"] etc