I am trying to create a basic WPF application that can store an encrypted password in SQL Server 2008 and also retrieve back the password when the user tries to login but I am getting an error after following this article
http://www.dreamincode.net/forums/topic/123865-one-way-encryption/
I read thru rainbow attacks and salting and hashing..
I tried some code but getting an error
The error I am getting is
string or binary data would be truncated
I read this article and tried to convert the textbox.text to string and also tried typing only one alphabet in the password texbox but still does not work ("I changed the connstring for security reasons as the connstring is working and there is no problem with that")
private void button1_Click(object sender, RoutedEventArgs e)
{
string strPassword;
SqlConnection cs= new SqlConnection("Data Source=STEVEJOBS;Initial Catalog=Test database;Integrated Security=True");
SqlDataAdapter da = new SqlDataAdapter();
da.InsertCommand = new SqlCommand("INSERT INTO Member_info(Name,Username,Password,Email,Member) VALUES(#Name,#Username,#Password,#Email,#Member)", cs);
da.InsertCommand.Parameters.Add("#Name", SqlDbType.NVarChar).Value = Name_tb.Text;
da.InsertCommand.Parameters.Add("#Email", SqlDbType.VarChar).Value = Email_tb.Text;
da.InsertCommand.Parameters.Add("#Username", SqlDbType.VarChar).Value = Username_tb.Text;
//MD5CryptoServiceProvider md5Hasher = new MD5CryptoServiceProvider();
//byte[] hashedBytes;
//UTF8Encoding encoder = new UTF8Encoding();
//hashedBytes = md5Hasher.ComputeHash(encoder.GetBytes(strPassword));
//SqlParameter paramPwd;
//paramPwd = new SqlParameter("#Password", SqlDbType.Binary, 16);
//paramPwd.Value = hashedBytes;
//da.InsertCommand.Parameters.Add(paramPwd);
da.InsertCommand.Parameters.Add("#Password", SqlDbType.VarChar).Value = HashPassword(Password_tb.Text.ToString());
da.InsertCommand.Parameters.Add("#Member", SqlDbType.NText).Value =Myes_rb.Content ;
cs.Open();
da.InsertCommand.ExecuteNonQuery();
cs.Close();
MessageBox.Show("Sucessfully added");
}
static string HashPassword(string pasword)
{
byte[] arrbyte = new byte[pasword.Length];
SHA256 hash = new SHA256CryptoServiceProvider();
arrbyte = hash.ComputeHash(Encoding.UTF8.GetBytes(pasword));
return Convert.ToBase64String(arrbyte);
}
Thks for the help!
This error appears when you try to insert a string with more characters than specified in column definition. Make your string columns wider.
To identify column that triggers this error, You can change your INSERT statement by eliminating parameters one by one (remove da.InsertCommand.Parameters.Add line for that column and in VALUES part of INSERT statement put a constant like 'John').
EDIT#1:
Continue eliminating columns one by one (just like You did with password column) and once insert statement doesn't fail, You will know what column caused error. Then debug to find out the length of value you are assigning to (failing) column parameter. Length of that column in database must be >= than length of value You are trying to insert.
Another thing to note: at the time of writing your question, You thought that password column is problem, but maybe some other column is problem. And only solution to this error is to make all columns wide enough so values can be stored in them.
EDIT#2:
Use Password property to get text user typed in:
da.InsertCommand.Parameters.Add("#Password", SqlDbType.VarChar).Value =
HashPassword(Password_tb.Password);
To get the length of hashed password use this code instead:
string pwdHash = HashPassword(Password_tb.Password);
da.InsertCommand.Parameters.Add("#Password", SqlDbType.VarChar).Value = pwdHash;
Put breakpoint on the second line and check the length of pwdHash string. Password column in database table must be equal or greater to this length.
Ok, you are totally off. YOu ahve tons of issues. Lets start:
I am trying to create a basic WPF application that can store an encrypted password in the SQL
SERVER 2008 and also retrieve back the password when the user try's to login but i am getting an
error after following this article http://www.dreamincode.net/forums/topic/123865-one-way-
encryption/
Fail, fired. See, - one way hashing (NOT encryption) is called so because it is one way. NO WAY TO RETRIEVE THE PASSWORD WITHOUT BREAKING IT. Program will never work.
also tried typing only one alphabet in the password texbox but still doesnot work
Read the documentation how salting works. SHA converts the input into a binary randum number of specific length. It is totally irrelevant whether you feed it 1 or 1000 character long passwords, the result will always be a fixed lengh binary code.
return Convert.ToBase64String(arrbyte);
This is quite irregular. Most people will convert the arrays into HEX (fixed length, easy to read / write for debugging) and use this.
Anyhow, write out the LENGTH of the string you return here. CHeck all parameters you enter against table structure lengh. Finished.
And you still fail the homework - SHA is not retrievable without breaking.
basic WPF application that can store an encrypted password in the SQL SERVER 2008 and also
retrieve back the password when the user try's to login
will never be achieved with this approach.
Related
I've a window in my WPF Project which helps the user to show the forgotten password, if the two security questions are being answered correctly. Unfortunately, my code doesn't work properly, therefore i need your kindly help.
In my code, i tried to read first and second answers from the textboxes, if they are match with S_Question1 and S_Question2 into SQL Server table, then should show the Psswrd, which has the same fields into the record.
I really appreciate your gently feedback!
My XML Code:
<StackPanel HorizontalAlignment="Center"
VerticalAlignment="Center"
Grid.Row="1">
<TextBox x:Name="SecurtyQuestionMother" Width="385"/>
<TextBox x:Name="SecurityQuestionSchool" Width="385" Margin="0 10 0 0"/>
<StackPanel Orientation="Horizontal"
HorizontalAlignment="Center"
Margin="10">
<Button Name="match"
Content="match"
Width="50"
Click="CheckPassword"/>
</StackPanel>
<Label x:Name="PasswordApears"/>
</StackPanel>
Code behind:
private void CheckPassword(object sender, RoutedEventArgs e) //updated...
{
SqlConnection conn = new SqlConnection(connectionString);
string sql = "select * from Ceo where S_Question1 =#one and S_Question2=#two;";
SqlCommand command = new SqlCommand(sql, conn);
command.Parameters.AddWithValue("#one", securityQ_mother_textbox.Text).SqlDbType = SqlDbType.Char;
command.Parameters.AddWithValue("#two", securityQ_school_texbox.Text).SqlDbType = SqlDbType.Char;
conn.Open();
SqlDataReader reader = command.ExecuteReader();
while (reader.Read())
{
if ((reader["S_Question1"]).ToString() == securityQ_mother_textbox.Text || reader["S_Question2"].ToString() == SecurityQuestionSchool.Text)
{
PasswordApears.Content = $"Password is: {reader["Psswrd"]}"; //PasswordApears <- is a label
}
else
{
PasswordApears.Content = "Didn't match";
}
}
conn.Close(); }
And this is the SQL Server Table:
I really don't mean to come off as- well- mean, but there is just so much wrong with how you are doing this. Please, take the time to read this answer and study up. It will make you a better developer.
Password Security
(Security standards change as threats evolve, make sure you're up to date on the latest best practices)
NEVER STORE PLAIN TEXT PASSWORDS.
No secure website or application on Earth actually stores a user's password for authentication use. Instead, they do something called "hashing". Hashing is a one-way process that transforms an input into a statistically unique output of gibberish. This gibberish is called a "hash". The same input always produces the same hash, but the hash can't be converted back into the original input.
The hash is the thing that is stored in a database, not the password.
You can tell if the user entered the right password, because you can hash what they entered and compare it to the hash of the valid password. But since hashing is a one-way process, a hacker can't get the hash and then use it to find out the user's password in the event of a security breach.
This is why no secure website or application will ever send/show you your password if you forget it. They don't actually have it, just the hash. The best they can do is allow you to set a new password to replace the old one.
Note: This is just a summary and not at all a full explanation of the proper technique for storing sensitive information like passwords. It leaves out many details (such as "salting"). Anyone working with this type of data should study the current best practices thoroughly.
SQL Injection
NEVER PUT USER-ENTERED TEXT DIRECTLY INTO AN SQL STATEMENT
You are currently creating your SQL query by taking the text input form the user and sticking it directly into the query string. You expect that the user will enter a legitimate answer, but they could enter anything else- including other SQL commands.
For exmaple, if the user entered this into securityQ_mother_textbox:
' OR 1=1--
Then your SQL statement would become:
select Psswrd from Ceo where S_Question1 ='' OR 1=1--' and S_Question2='{two}';
Which would return every record. They could also easily add other statements, like DELETE and wipe your whole database. This type of malitous input is called "SQL injection", because the attacker is "injecting" their SQL code into your application.
The right way to do this is using parameters:
string sql = "select Psswrd from Ceo where S_Question1 = #one and S_Question2= #two;";
...
command.Parameters.AddWithValue("#one", securityQ_mother_textbox.Text).SqlDbType = SqlDbType.NVarChar;
command.Parameters.AddWithValue("#two", securityQ_school_texbox.Text).SqlDbType = SqlDbType.NVarChar;
The SqlParameter class, "sanitizes" the input before adding it to the string. That means it changes the input in such a way that it can't be interpreted as anything other than a variable.
Always use variables; never put the input directy into the command.
IDisposable
Using objects that implement IDisposable
SqlConnection, SqlCommand and SqlDataReader all implement the IDisposable interface. Per the documentation linked above, this means they should be decalred in a using block. This would also call conn.Close for you.
The Actual Problem With Your Code
In your SQL statement, you only select the Psswrd column, this means that only that column will be returned by reader. Calls like reader[6] and reader[7] will fail because only one column is actually available.
Also, columns are usually accessed by name, not index (number). For example reader["First_Name"].
I need to display some data from Oracle. But Address name contains some special character like "Č, Ć, Š, Đ, Ž" etc. These special characters are displayed properly in database, but when I try to get values from database using c#, I get this from dataReader:
for Č, I get È
for č, I get è
for Ć, I get Æ
for ć, I get æ
for Ž, I get \u008e
for ž, I get \u009e
for š, I get \u009a
What I need to do to get from dataReader the same value like value from database? I didn't find the answer on google yesterday, so I decided to ask here.
Someone please help.
I'm using C# and Visual Studio 2015. I just need to select rows from base, I'm not able to update or insert values. This is my code:
private OracleConnection _connection;
private OracleCommand _command;
public List<Address> GetAddressList()
{
string query = "SELECT id, name FROM address";
_command = new OracleCommand(query, _connection);
OracleDataReader dataReader = _command.ExecuteReader();
List<Address> addressList = new new List<Address>();
while (dataReader.Read())
{
Address address = new Address
{
id = dataReader["id"].ToString(),
Name = dataReader["name"].ToString()
};
addressList.Add(address);
}
dataReader.Close();
return addressList;
}
This question is basically the same: Trouble using/displaying special characters from Oracle db in .Net app
You have some data stored in database and You need to display them. There are several things that must be checked:
1) Have I been using the right encoding during save?
2) Are the information stored in the database in readable form (correct encoding codec)?
3) Am I using correct encoding during data receive (decoding)?
It is important to check all 3 things, as You might encode them good, but Oracle (or any DB) will just convert them to final encoding, which might not support the characters. Also when You will query this against DB, it will return in the set encoding and You will be converting it to some final form.
EDIT:
As the database is storing all the characters in this encoding: WE8ISO8859P1, I would recommend You to read other StackOverflow answer:
- NLS_CHARACTERSET WE8ISO8859P1 and UTF8 issues in Oracle
Problem is that the characters are stored as 1 byte (8 bits) only and the encoding is for American_America, You will be unable to store such characters as 'ž' 'č' or others.
Solution would be to change Encoding of the Table and/or better for whole Database.
EDIT #2 as Wernfried Domscheit stated:
You database character set is WE8ISO8859P1. This character set does not support characters like Č, Ž, š, see ISO-8859-1. Unless you use NCHAR data type, resp. migrate your database character set to something else you cannot insert or select such characters.
I've used this
http://jphellemons.nl/post/Easy-generate-SHA1-in-AspNet
To hash password that has been created while registering, but when I try to login it doesn't let me.
How do I make it the hash read as a normal text that has been putted into form before it was submited and converted into hash?
#Edit.
Though I can login with hashed password when I use the whole hash text..but it is not what I want D:
#edit2
this is how login thing looks like
using (SqlConnection con = new SqlConnection(ConfigurationManager.ConnectionStrings["Connect"].ToString()))
{
SqlCommand cmd = new SqlCommand();
cmd.Connection = con;
cmd.CommandText = #"SELECT * FROM users
WHERE login = #username
AND pass = #password";
cmd.Parameters.AddWithValue("#username", TextBox_Login.Text);
cmd.Parameters.AddWithValue("#password", TextBox_Password.Text);
con.Open();
}
Hashing is one way. You cannot convert it back to the text you started with (generally speaking of course).
It sounds like when you login, you're missing a step to hash the text that was put into your login and compare to the stored hash. You mentioned that using the hash text in the login form works, but if you simply hash the login password text and use that for the authentication/comparison instead, you'll get the intended results.
If you hash TextBox_Password.Text and then pass it as a parameter instead of passing the text directly, you should get the result you're after. Although you'll want to do a little research and implement a salt on your hashes eventually.
The idea of the hash is that it's really easy to encrypt and really hard to decrypt. The way to login is to run the attempted password through the same hash algorithm and then compare that hash with the stored hash for the user. You should never be able to read the stored hash as plain text.
I'm trying to write a c sharp program where I enter data to database and read data from database
Database name is kangoojump and I have an admin table here to store id,username and password
I created a login screen for my program and want to type in my username& password and when I press the login button I want to retrieve data from the database table and compare the two and if they match give access to next form...
here is my code
MySqlCommand SelectCommand = new MySqlCommand(" SELECT username FROM kangoojump.admin where _id=1", mcon);
MySqlDataReader myReader;
mcon.Open();
myReader = SelectCommand.ExecuteReader();
while (myReader.Read())
{
temp1 = myReader["username"].ToString();
}
I have created a username,password,temp1,temp2 of type string in my function but
when I try to run the program I get the error that " use of unassigned variable 'temp1' "
what is the problem with my code?
Thanks
Where have you defined temp1 ?
when defining temp1
do it as follows -
string temp1 = string.Empty;
The problem has to do (in part) with this line of code:
while (myReader.Read())
You and I are smart enough to know that the database query will always return a row, but the compiler is not. This because we have information that is not available to the compiler: we know there will be an admin record. The compiler can't know this. Therefore, the compiler can't guarantee that your code will ever enter the body of that while loop. This means it also can't guarantee that you will ever assign a value to the temp1 variable... hence, your potentially "unassigned variable 'temp1'": the compiler can't guarantee you've written a reasonable value to the variable yet, and you're not allowed to read from it until you do.
The easy solution is to just assign a basic value to the variable when you first declare it:
string temp1 = "";
And while we're here: never ever ever store plain-text passwords. Store one-way password hashes.
I'm doing some encryption tasks in C# and ran into an issue I can't quite figure out. I sometimes get very complex salted hash strings for users passwords and these strings, for some reason, aren't getting stored in the database correctly.
I'm using an 8-byte salt randomly generated from the RNGCryptoServiceProvider class. I am using the SHA256Managed class as my HashAlgorithm. I'm getting the string to store from the bytes created via the ASCIIEncoding.Default.GetString() method. The column these values are being stored in is of type (NVARCHAR(50), NULL). I'm storing them using the SqlCommand class.
I can see the exact string fine when stepping through my code and using the immediate window. It seems like the problem is happening when I call cmd.ExecuteNonQuery(). Should I be doing it differently than below?
string query = #"UPDATE User SET password = #password WHERE id = #userID";
cmd = new SqlCommand(query, conn);
cmd.Parameters.AddWithValue("#password", encryptedPassword);
cmd.Parameters.AddWithValue("#userID", userID);
int rowsAffected = cmd.ExecuteNonQuery();
If you require any further information, let me know. I just don't wanna put too much on here about my exact algorithm or the results of it.
Thank you.
Try using Convert.ToBase64String() instead for encoding byte array into string. This should solve your problem.