I am trying to learn cryptography with saving passwords in database with hashing and salting, so I decided to make a login-system trying implementing this system.
My database consist of
- UserID int PK
- Username varchar(250)
- Salt varbinary(64)
- Password varbinary(64)
- RegDate datetime
- Email varchar(250)
I am using PBKDF2, but it seems like this isn't a hashing / salting method, what is it if it isn't?
If so I am doing this right?
My Keys
private const int SALT_SIZE = 64;
private const int KEY_SIZE = 64;
Inserting data to the database
public static void RegisterMe(string _username, string _password, string _email)
{
using (var cn = new SqlConnection(User.strcon))
{
string _sqlins = @"
INSERT INTO
[User]
([Username],[Salt],[Password],[RegDate], [Email])
VALUES
(@Username, @Salt, @Password, CURRENT_TIMESTAMP, @Email)";
var cmd = new SqlCommand(_sqlins, cn);
cn.Open();
using (var deriveBytes = new Rfc2898DeriveBytes(_password, SALT_SIZE))
{
byte[] salt = deriveBytes.Salt;
byte[] key = deriveBytes.GetBytes(KEY_SIZE);
// save salt and key to database
cmd.Parameters.AddWithValue("@Username", _username);
cmd.Parameters.AddWithValue("@Password", key);
cmd.Parameters.AddWithValue("@Salt", salt);
cmd.Parameters.AddWithValue("@Email", _email);
}
cmd.ExecuteNonQuery();
}
}
Checking if user is valid
public bool IsValid(string _email, string _password)
{
using (var cn = new SqlConnection(strcon))
{
byte[] salt = { }, key = { };
string _sql = @"
SELECT
SALT,
[Password],
UserID
FROM
[User]
WHERE [Email] = @email";
SqlCommand cmd = new SqlCommand(_sql, cn);
cmd.Parameters.AddWithValue("@email", _email);
cn.Open();
SqlDataReader reader = cmd.ExecuteReader();
if (reader.Read())
{
salt = reader.GetSqlBytes(0).Value;
key = reader.GetSqlBytes(1).Value;
reader.Dispose();
cmd.Dispose();
using (var deriveBytes = new Rfc2898DeriveBytes(_password, salt))
{
byte[] newKey = deriveBytes.GetBytes(KEY_SIZE); // derive a 20-byte key
return newKey.SequenceEqual(key);
}
}
else
{
reader.Dispose();
cmd.Dispose();
return false;
}
}
}
My system works, it is setting data into the database as bytes and if the user is typing the correct password it returns true. But is this the right way? Is this even hashing / salting?
Rfc2898DeriveBytes
uses SHA-1. For checking if a password is correct, you only need to recalculate the PBKDF2 value and compare, no need for additional cryptography. – Windsail