Reputation: 1215
I have managed to write a set of methods to get password, add salt to it, and store salt and hashed password in a database.
But when I try to retrieve and print the salt it prints System.byte[]
instead of salt string. I think there's a problem with return types of methods. Here are my methods,
class HashSalt
{
private readonly int num_of_iterations;
// --- constructor to initialize num_of_iterations
public HashSalt(int numOfIterations)
{
num_of_iterations = numOfIterations;
}
// --- Generate Salt ---
public string generateSalt()
{
var salt = new byte[32];
var randomProvider = new RNGCryptoServiceProvider();
randomProvider.GetBytes(salt);
return Convert.ToBase64String(salt); // returns salt as a string
}
// --- converts salt string into byte[]
public byte[] saltToByte(string salt)
{
var byteSalt = Convert.FromBase64String(salt);
return byteSalt;
}
// --- Generate hash of(pass+salt) ---
public string generateHash(string password, byte[] salt)
{
var rfc2898 = new Rfc2898DeriveBytes(password, salt, num_of_iterations);
var Password = rfc2898.GetBytes(32); // gives 32 byte encoded password
return Convert.ToBase64String(Password); // returns hash
}
}
Code used to save into database
DbHandler db = new DbHandler();
MySqlCommand cmd = new MySqlCommand("INSERT INTO `student`(`indexno`,`firstname`,`lastname`,`address`,`gender`,`dob`,`email`,`faculty`,`mobile`,`password`,`salt`)VALUES(@index, @firstname, @lastname, @address, @gender, @dob, @email, @faculty, @mobile, @password, @salt);", db.getConnection());
var salt = hashSalt.generateSalt(); // generates random salt type string
var byteSalt = hashSalt.saltToByte(salt); // gets byte[] from salt string
cmd.Parameters.Add("@index", MySqlDbType.VarChar).Value = txtindex.Text;
cmd.Parameters.Add("@firstname", MySqlDbType.VarChar).Value = txtfname.Text;
cmd.Parameters.Add("@lastname", MySqlDbType.VarChar).Value = txtlname.Text;
cmd.Parameters.Add("@address", MySqlDbType.VarChar).Value = txtaddress.Text;
cmd.Parameters.Add("@gender", MySqlDbType.VarChar).Value = getGender();
cmd.Parameters.Add("@dob", MySqlDbType.Date).Value = dateDob.Value.Date;
cmd.Parameters.Add("@email", MySqlDbType.VarChar).Value = txtemail.Text;
cmd.Parameters.Add("@faculty", MySqlDbType.VarChar).Value = cmbfaculty.GetItemText(cmbfaculty.SelectedItem);
cmd.Parameters.Add("@mobile", MySqlDbType.VarChar).Value = txtmobile.Text;
cmd.Parameters.Add("@password", MySqlDbType.VarChar).Value = hashSalt.generateHash(txtpassword.Text, byteSalt); // get (password+salt) hashed from db
cmd.Parameters.Add("@salt", MySqlDbType.VarBinary).Value = salt;
db.openConnection(); // open connection
// execute query
if (cmd.ExecuteNonQuery() == 1)
{
MessageBox.Show("Record added!", "Success!", MessageBoxButtons.OK, MessageBoxIcon.Information);
}
else
{
MessageBox.Show("Failed!, please retry", "Error!", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
db.openConnection(); // close connection
Hoping to solve this issue.
Upvotes: 0
Views: 655
Reputation: 9804
But when I try to retrieve and print the salt it prints System.byte[] instead of salt string. Hoping to solve this issue.
If not given a String, WriteLine and most similar code will take a object and call ToString()
on it.
The default implementation of ToString()
returns the class name as a string - System.byte[]
in your case - which can then be printed. Classes need to override ToString()
if they want something a bit more useful for debugging. String for example does, returning itself or a copy of itself (I think the former, but I would have to look into the code).
There is no automatic that will try to iterate over arrays or other collections either. It will only automatically print the class name. If you want the contents of a collection printed, you have to iterate over it manually - and potentially recursively - adding proper separator and annotation chars. A simple foreach should do for this case. However I am not sure how you want to convert each byte into a string or char here. Usually you would print one byte as a 2 digit hexadecimal value.
Upvotes: 1
Reputation: 1215
Found it, the problem is with the datatype of the salt column in the database, it set to varBinary but return type of the method generateSalt()
is string and that string is send to store into the database. So all I had to do is change the datatype of salt column in the database to varchar.
Upvotes: 0