我正在使用mysql数据库并尝试在那里创建一个用户。密码是散列。当我使用context.useraccount.add(user)和context.savechanges()添加到数据库时,效果很好,但是使用executesqlcommmand会使密码不起作用。
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));
它给出此异常:{mysql.data.mysqlclient.mysqlexception(0x80004005):不正确的字符串值:'\x90]\x0e\x80\xb1\xff…'对于第1行的“password”列---->mysql.data.mysqlclient.mysqlexception(0x80004005):不正确的字符串值:'\x90]\x0e\x80\xb1\xff…'对于第1行的“password”列
我尝试将db中的列值更改为varbinary(从varchar开始),然后我可以插入它,但是它在db中变成了一个blob,当我再次尝试读取它时,它就不起作用了。
如何将哈希正确发送到数据库?
edit---创建哈希的代码
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---密码类型为byte[]
这是如果我将数据库中的password和saltedpassword类型更改为varbinary。当我使用varchar时,它给出了我之前粘贴的错误,并且没有任何内容发送到db。
文本图像
更新--已解决
所以我在modelbuilder.entity中输入的密码varchar的值是错误的,而它应该是varbinary。不过,它在某种程度上与context.useraccount.add(user)和context.savechanges()一起工作。
谢谢大家的帮助!
2条答案
按热度按时间bvjveswy1#
解释这个答案,因为它也适用于你的情况
试图通过jdbc将utf-8插入mysql时“字符串值不正确”?
mysql的utf8编码只支持3字节编码的字符。不管字符“\x90]\x0e\x80\xb1\xff”是什么,可能都需要3个以上的字节来编码,这就是为什么mysql会对你大喊大叫。
验证您用来对这些密码进行编码的任何方法都限制为utf8格式,这样可以防止此错误再次发生。
我看不到散列这些的方法,但这将确保您使用utf8编码
jbose2ul2#
密码哈希是字节数组,不能存储在c字符串中。它们还必须储存在
BINARY
(或VARBINARY
)列,而不是VARCHAR
列。但是它在数据库中变成了一个blob,当我再次尝试阅读它时,它就不起作用了
要验证用户的密码,您应该读回密码salt(作为
byte[]
),使用相同的salt对(纯文本)密码进行散列,然后将新生成的散列与从数据库检索到的密码散列进行比较(作为示例)byte[]
). 不要尝试将密码哈希转换回c#string
.