You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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#代码生成的哈希与数据库存储值不匹配。

解决方式二选一:

  1. 强制C#参数为非Unicode类型
    替换参数添加代码,明确指定SqlDbType.VarChar:

    cmd.Parameters.Add("@password", SqlDbType.VarChar, 100).Value = form.password;
    
  2. 调整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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.16 05:05:21