C# SQLite encryption hashing SHA1 - c#

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.

Related

How to use custom Methods in LINQ Query

I have the following issue: I am currently working on a ASP .net core entity framework backend and have the problem that I need to use a Custom Method in LINQ Query and getting a error when doing this. I
researched and found out that it is possible to write custom functions, that will be translated to sql, but I think that there is not a big scope for doing this. (e.g: SQL will not be able to use Libaries and hash strings).
Another way that I have heard of ist to convert my Database to a Enumberale and then apply my Custom Methods on it, which works, but is not that performant, because I am saving my whole Database in my memory, which gets very slow when having a huge amount of data. So my question is, if there is a performant solution to perform custom methods in LINQ queries?
My detailed problem is, that I have saved my salted passwords hashed in my database and when someone want s to log in to his account I have to compare the password in the database with the salt + user password input, that has to get hashed in my where clause. It would work if I wouldnt use salts, because then, I would only have to hash the user input, which is not column of the database.
What you should do is - calculate the hash and salt in the backend, and use the computed hash in your WHERE statement. In this case you don't need to call your methods from SQL equally you don't need to pull entire db (or table) into memory to compute hash.
As I don't know your code, the pseudo-code approach would be:
var user = service.GetUserByEmail(email);
if (user == null) {
//Invalid User
}
var hash = ComputeHash(user.Salt, inputPwd);
if(user.PasswordHash == hash) {
//User is logged in
} else {
//Invalid Password or email
}

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.

Flow of validating a user with hashed password?

I was reading this article about hashing passwords when I came to this part:
To Validate a Password
Retrieve the user's salt and hash from the database.
Prepend the salt to the given password and hash it using the same
hash function.
Compare the hash of the given password with the hash from the
database. If they match, the password is correct. Otherwise, the
password is incorrect.
But I am a little confused with the flow this would follow, for example lets assume I have a database with a user table with id,name,password and email and in order to login to some app I need to input my email and password.
Following the the steps above, I first need to get the salt+hashed password of said user stored in the database.
Question:
Assuming I am using a simple stored procedure would the only way be to do it like this...
CREATE PROCEDURE [dbo].[sp_validate_user]
#us_email VARCHAR (MAX)
AS
BEGIN
-- SET NOCOUNT ON added to prevent extra result sets from
-- interfering with SELECT statements.
SET NOCOUNT ON;
-- Insert statements for procedure here
SELECT us_id,
us_name,
us_pass,
us_email
FROM Users
WHERE us_email = #us_email
END
Then following step two and three:
public static bool ValidatePassword(string inputPassword, string storedPassword)
{
// Extract the parameters from the hash
char[] delimiter = { ':' };
string[] split = storedPassword.Split(delimiter);
int iterations = Int32.Parse(split[ITERATION_INDEX]);
byte[] salt = Convert.FromBase64String(split[SALT_INDEX]);
byte[] hash = Convert.FromBase64String(split[PBKDF2_INDEX]);
byte[] testHash = PBKDF2(inputPassword, salt, iterations, hash.Length);
return SlowEquals(hash, testHash);
}
My concern comes from the fact that if I am creating objects with the data pulled from the table, doesn't that make the information within vulnerable somehow?
Also does that mean that the only way to use this validation is pulling all the user's information based only on a username/email just to check in runtime if the input password and the hashed one match and then letting said user access the information?
I'm sorry if this sounds confusing but any insight would be great.
It looks like you may be thinking of it backwards. The salt is added to the cleartext password before passing to the hash function. Store the end result in the database.
Commonly, the salt is the username. Something unique to each user to thwart dictionary attacks. (A dictionary attack relies on the economy of scale by cracking one password and then looking for other instances of the same crypto-text. It used to work especially well on very large user databases like well known sites that have millions of users, but hopefully those sites use proper salting and key derivation nowadays).
So for username u, password p, assume SHA2 is hash function. Concatenate u + p to get a salted value, then hash it.
hashtext = SHA2(u + p) // in this case, + is concatenate
hashtext is what you store in the database.
For the login, user enters his username u2 and password p2:
tryhash = SHA2(u2 + p2)
Query database for a user record matching u2, with password hashtext of tryhash
Lets say you have an MVC action receiving loginViewModel which is populated with cleartext email or username as well as cleartext password, entered from the page:
var loginUser = new User(loginViewModel);
CalcHash(loginUser);
var realUser = users.Find(loginUser.username);
if(realUser.HashPassword == loginUser.HashPassword)
// success
While it is also possible to add the hashed password as a second argument to your Data Access method, ie. users.Find(username, hashPass), it is usually not done this way, because you need to access the user record even if the password fails, in order to increment password failure count and lockout the account.
The article covers ASP.NET (C#) Password Hashing Code but you seem to want to use a database?
You have three things to worry about; the unique key for the user (username), your chosen hashing algorithm and adding a salt to the password attempt (prevents rainbow table attacks).
To validate a password you should create a sql stored procedure that accepts the username and password attempt as parameters. This data is in plain text and has been entered into the web form, passed to the web server and will be passed into the database server via the stored procedure.
The stored procedure will do the following;
Lookup the data row for user based on matching the username parameter with the username field and
select the stored salt field
Append the salt from (1) to the password parameter and hash the result
Lookup the data row for the user based on matching the username parameter with the username field
and the hash result from (2) with the hashed password field.
If there is no row found the password hashes don't match and are wrong so return a suitable error code
If there is a row found return the useful user data i.e. First Name, Address
If the stored procedure handles all this then the web server never needs to know what the salt is or the hashing algorithm. At no point does the hash result or the salt get transmitted out of the database server.
I think you understood it correctly, this is the usual workflow:
Get the password-hash by username SELECT password_hash FROM user WHERE email=?.
Extract the salt from the password_hash, or get the salt from a separate field.
Calculate the hash of the entered password with the extracted salt and compare the hashes.
Validating the password cannot be done in a single query, because you first have to extract the salt. Appropriate hash functions like PBKDF2, BCrypt or SCrypt are often not supported by the database system, so you have to do the validation in your code. Additionally to the salt you also have to store other parameters like the cost factor and the algorithm (to be future-proof), so it is a good idea to store all these parameters in the same database field.
The salt should be a random string of at least 20 characters, so it is not safe to use the username as salt, or to derrive the salt from other information.

Encrypted string not being stored in database correctly

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.

How to set criteria for NHibernate for MySQL MD5?

In MySQL i can do
SELECT * FROM table WHERE MD5(column) = 'blablabla';
But how do i do that with NHibernate and Criteria functions?
I got a value alrady as md5 but the column in the database is not md5 hashed...
I working in C#.
Some ideas?
In Java, you can use Expression.Sql, the same should work in C#, something like:
var table = session.CreateCriteria(typeof(Table))
.Add(Expression.Sql("MD5(column)= ?", value, NHibernateUtil.String))
.UniqueResult<Table>();
where value is the hex-encoded value of your MD5 hash.
Although, one word of caution - if the value stored in the database is the user's password, then your design is flawed and insecure. You should only store salted, hashed passwords in the database. No, you shouldn't even do that, you should right away use bcrypt, scrypt or PBKDF2 for that.

Categories

Resources