I'm using MySql DB and trying to create a user there. The password is a hash. When I use the Context.Useraccount.add(User) and Context.SaveChanges() adding to the database works just fine, but using ExecuteSqlCommmand makes the password not work.
var sql = @"INSERT INTO useraccount
(UserId,UserName,Password,CustomerId,PasswordSalt,CreatedDate)
VALUES
(@UserId, @UserName,@Password,@CustomerId, @PasswordSalt, @CreatedDate)";
int rows = _context.Database.ExecuteSqlCommand(
sql,
new MySqlParameter("@UserId", user.UserId),
new MySqlParameter("@UserName", user.UserName),
new MySqlParameter("@Password", user.Password),
new MySqlParameter("@CustomerId", user.CustomerId),
new MySqlParameter("@PasswordSalt", user.PasswordSalt),
new MySqlParameter("@CreatedDate", MySQLFormatDate));
It gives this exception: {MySql.Data.MySqlClient.MySqlException (0x80004005): Incorrect string value: '\x90]\x0E\x80\xB1\xFF...' for column 'Password' at row 1 ---> MySql.Data.MySqlClient.MySqlException (0x80004005): Incorrect string value: '\x90]\x0E\x80\xB1\xFF...' for column 'Password' at row 1
I tried changing the Column value in the DB to varbinary (from varchar) and then I can insert it, but it becomes a blob in the DB and it doesn't work when I try to read it again.
How can I send the hash correctly to the DB?
Edit--- code for creating the hash
private static void CreatePasswordHash(string password, out byte[] passwordHash, out byte[] passwordSalt)
{
if (password == null) throw new ArgumentNullException("password");
if (string.IsNullOrWhiteSpace(password)) throw new ArgumentException("Value cannot be empty or whitespace only string.", "password");
using (var hmac = new System.Security.Cryptography.HMACSHA512())
{
passwordSalt = hmac.Key;
passwordHash = hmac.ComputeHash(System.Text.Encoding.UTF8.GetBytes(password));
}
}
edit2--- password types are byte[]
UPDATE -- SOLVED
So I had the wrong value in the modelbuilder.entity for the password I had VarChar there when it should've been VarBinary. Somehow it worked with Context.Useraccount.add(User) and Context.SaveChanges() though.
Thanks to everyone for the help!
Paraphrasing the answer from this answer since it applies to your situation as well
"Incorrect string value" when trying to insert UTF-8 into MySQL via JDBC?
MySql's utf8 encoding only supports characters that can be encoded in 3 Bytes. Whatever character '\x90]\x0E\x80\xB1\xFF' is probably takes more than 3 bytes to encode and that is why MySql is yelling at you.
Verify that whatever method you are using to encode these passwords is limited to a utf8 format and that should prevent this error from re-occuring.
I can't see your method for hashing these, but this will ensure you are encoding using utf8
byte[] salt = // Salt
byte[] encodedValue = Encoding.UTF8.GetBytes(value);
byte[] saltedValue = value.Concat(salt).ToArray();
byte[] hashedValue = SHA256Managed().ComputeHash(saltedValue);
Password hashes are byte arrays, and cannot be stored in a C# string. They also have to be stored in a BINARY
(or VARBINARY
) column in the database, not a VARCHAR
column.
but it becomes a blob in the DB and it doesn't work when I try to read it again
To verify the user's password, you should read back the password salt (as a byte[]
), hash the (plain text) password with the same salt, then compare the newly-generated hash to the password hash retrieved from the database (as a byte[]
). Do not try to convert the password hash back to a C# string
.
User contributions licensed under CC BY-SA 3.0