SQL Server与C#中MD5密码验证不一致问题排查
MD5密码验证:SQL查询正常但C#代码无法匹配记录
问题:在SQL Server端执行MD5密码验证查询可正常返回用户记录,但使用C#编写的同逻辑密码验证代码无法进入读取到记录的分支,请问哪里存在遗漏?
SQL Server端测试代码
declare @password varchar(100) = '12345aA!' select user_id, username from tblusers where password=CONVERT(NVARCHAR(32),HashBytes('MD5', @password), 2);
C#验证代码
var query = "select user_id from tblusers"; query += " where password=CONVERT(NVARCHAR(32), HashBytes('MD5', @password), 2);"; using (SqlConnection con = new SqlConnection()) { con.ConnectionString = _config.GetConnectionString("backend"); con.Open(); using (SqlCommand cmd = new SqlCommand()) { cmd.Connection = con; cmd.CommandType = System.Data.CommandType.Text; cmd.CommandText = query; cmd.Parameters.AddWithValue("@password", form.password); using (SqlDataReader dr = cmd.ExecuteReader()) { if (dr.Read()) { // 无法进入此分支 } } } }
问题原因及解决方法
核心问题是字符串类型不匹配:
- SQL测试代码中
@password声明为varchar(100)(非Unicode字符串),而C#中AddWithValue会将默认的Unicode字符串(string类型)自动映射为SQL的nvarchar类型。 HashBytes处理varchar和nvarchar时生成的MD5哈希值完全不同,导致C#代码生成的哈希与数据库存储值不匹配。
解决方式二选一:
强制C#参数为非Unicode类型
替换参数添加代码,明确指定SqlDbType.VarChar:cmd.Parameters.Add("@password", SqlDbType.VarChar, 100).Value = form.password;调整SQL查询统一类型
修改SQL语句,将传入的nvarchar参数转为varchar后再计算哈希:select user_id from tblusers where password=CONVERT(NVARCHAR(32),HashBytes('MD5', CONVERT(VARCHAR(100), @password)), 2);
注意:MD5属于不安全的哈希算法,建议使用SHA-256等更安全的算法,并配合随机盐值存储密码,提升安全性。
内容的提问来源于stack exchange,提问作者Pankaj
相关产品推荐
相关产品推荐

