Encrypted string not being stored in database correctly - c#

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.

Related

How to read hashed password while login?

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.

C# SQLite encryption hashing SHA1

I have an application in C# and a database in SQLite. In database, I have a table with a few columns. In one of a columns, I have a value which is encrypted with SHA1 from query. But I need to use it in my C# app like this:
cmd.CommandText = "Select * from accounts where (username=#username and password=sha1(#password));";
I need to select the string value, for logging to app. I receive error: no such function sha1.
From other posts like: This one , I understand that I have to create another function for hashing with sha1? But I don't really understand how to do this..Can anybody help me? Sorry if it's duplicate but I didn't find the specified answer.
As SQLite does not implement any sha1 function by default, you would have to move the password hashing from the SQL query to your code.
Meaning your query should be :
cmd.CommandText = "Select * from accounts where (username=#username and password=#password);";
and you should pass the password like this :
cmd.Parameters.AddWithValue("#password", sha1(password));
And you should implement your own sha1 function
using System.Security.Cryptography;
...
string sha1(string input) {
byte[] byteArray = Encoding.UTF8.GetBytes(input);
string result="";
using (HashAlgorithm hash = SHA1.Create()) {
result=Convert.ToBase64String(hash.ComputeHash(byteArray));
}
return result;
}
Important
Using hashing function is considered quite insecure for storing password, you should consider learning about Key Derivation function, reading the wikipedia pages will lead you to C# implementation of such functions.

Having trouble plucking the correct value from my DB

Sorry for not putting the question in the title, the real problem is that I can't see an issue with my code but it's not producing what I want it to.
So I've written some code which is meant to take the database's Password field and inspect its value then store that value as a string within a password variable. In SQL Management studio the value is 'MyPass', that's what I'm expecting to get when I print out the password variable as a MessageBox. Instead I get two boxes, 'password' and then 'password123'. The only column within the table: Login, is one called Password.
Here is the using statement:
using(SqlConnection con = new SqlConnection(connectionString))
{
string query = "SELECT Password FROM LoginInfo";
con.Open();
//SqlCommand to be executed against my DB with the query text and the connection object.
SqlCommand myCommand = new SqlCommand(query, con);
//Sends CommandText to connection. Creates a
SqlDataReader read = myCommand.ExecuteReader();
while(read.Read())
{
//Convert read to IDataRecord.
ReadSingleRow((IDataRecord)read);
}
read.Close();
}
I apologize if my comments are incorrect, I wrote them down because they help me think.
You can read my interpretation of the code below and tell me what's wrong with my thinking process or you can just scour the code samples for errors.
My Interpretation (If you'll indulge me):
So, in the using statement we create a connection, a query string, an SqlCommand and an SqlDataReader. Passing the SqlCommand the query string and the connection object we then set its instance equal to an SqlDataReader, named 'read' with the method ExecuteReader() which takes the command text to wherever the connection is through the connection object.
Next we use a while loop, we use the .Read() to advance the reader on to the first record, since my db only has one record 'Password' this just moves it on to that. Within while we have the method ReadSingleRow which converts the reader instance into an IDataRecord: ((IDataRecord)read).
The ReadSingleRow method:
public void ReadSingleRow(IDataRecord record)
{
UserPass = record.GetString(record.GetOrdinal("Password"));
MessageBox.Show(UserPass);
}
the IDataRecord retrieves the string value of the oridinal(ID) password. My understanding is that it looks at the value of Password: Mypass, and then stores that within the UserPass string variable. The MessageBox of course blurts out the variable as a test to see if it worked. It didn't.
So my question is the annoying: why didn't this work? Perhaps I am miss-using the IDataRecord.

'String or binary data truncated' while inserting into SQL Server 2008

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.

how do I get a cell of data from a specific row in c# with a local sql database file

So im pretty much just messing with c# and sql databases and I created a database with a table that has 2 columns, one for username and one for password and I wanted to know how i would look up the row the username is in and get the corresponding password(cell next to it) so I could compare for a login aspx page
This is a question that is going to take you doing a bit of research. There are a plethora of tutorials on the internet on how to access data. Below I've included one way that you can return a single value for you to get started with. You'll need to include System.Data.SqlClient.
// See http://www.connectionstrings.com/ for how to build your connection string
SqlConnection sqlConnection1 = new SqlConnection("Your Connection String");
SqlCommand cmd = new SqlCommand();
Object returnValue;
cmd.CommandText = "SELECT COUNT(*) FROM Customers";
cmd.CommandType = CommandType.Text;
cmd.Connection = sqlConnection1;
sqlConnection1.Open();
returnValue = cmd.ExecuteScalar();
sqlConnection1.Close();
I lifted this example from http://msdn.microsoft.com/en-us/library/eeb84awz(v=vs.80).aspx
Wrong approach. Collect both the username and password, and look to see if there is a match in the database.
How to do it in C#? I like LINQ to SQL, even thought Microsoft recommends otherwise. Create a LINQ to SQL classes object in a C# project, call it MyContextClass, drop your database objects onto it. Then, in your code behind, write something like:
using (MyContextClass ctx = new MyContextClass) {
if (ctx.SingleOrDefault(f => f.Username == txtUsername.Text && f.Password == txtPassword.Text) != null) {
// The user got it right.
}
}
However, all the warnings about storing passwords in the comments above really do apply. Integrating those is left as an exercise for the user.

Categories

Resources