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

如何让C#匹配MySQL数据库中IPS/Invision Community的哈希密码

问题

现有运行IPS/Invision Community的网站,正在开发配套C#应用以共享同一数据库与认证系统。数据库中密码以哈希形式存储,示例哈希值如下:

$2y$10$Tu9ImODbXvVVtievNhkEIODyonQgclnDXQ.8N8mRPd2JMQYSDStqK

需要复现该哈希流程实现用户认证,已获取原网站的PHP代码(包含哈希生成、对比逻辑),目前配套C#代码已能检索用户记录,但未实现HashPassword方法导致认证失败,现有C#代码如下:

string server = "s570.use8.mysecurecloudhost.com";
string database = "nextgene_NGH";
string uid = "nextgene_NGH";
string password = "EXAMPLE PASSWORD";
string ssl = "None";

string connectionString = $"SERVER={server};DATABASE={database};UID={uid};PASSWORD={password};SSL Mode={ssl};";

// NEVER NEVER NEVER store an "exact password" in a database!!
string SQL = "SELECT * FROM `core_members` where name= @name AND hashed_password= @hash;";
var dt = new DataTable();

try
{
    using (var connection = new MySqlConnection(connectionString))
    using (var command = new MySqlCommand(SQL, connection))
    using (var da = new MySqlDataAdapter(command))
    {
        //NEVER NEVER NEVER use string concatenation to put user input in a query
        command.Parameters.AddWithValue("@name",  maskedTextBox1.Text);
        command.Parameters.AddWithValue("@hash", HashPassword(maskedTextBox2.Text));
  
        da.Fill(dt); //Fill opens and closes the connection
    }

    if (dt.Rows.Count == 0)
    {
        MessageBox.Show("Login Failed.");
        //button2.Visible = true;
    }
    else
    {
        MessageBox.Show("Login Successful.");
    }
}
catch (Exception ex)
{
    MessageBox.Show(ex.Message);
}

解决方案

1. 理解IPS密码哈希机制

示例哈希以$2y$开头,这是PHP中bcrypt哈希的标识(与标准bcrypt的$2a$兼容)。IPS使用PHP的crypt()函数生成该哈希,哈希值中已包含盐和算法参数(比如$10$代表工作因子为10),无需单独存储盐。

2. 安装BCrypt库

C#无内置bcrypt实现,需通过NuGet安装第三方库,推荐BCrypt.Net-Next(支持$2y$哈希,安全性更高):

  • 在Visual Studio中右键项目 → 管理NuGet程序包 → 搜索BCrypt.Net-Next并安装。

3. 修改C#认证逻辑

原代码错误在于试图生成哈希后直接在SQL中匹配,正确逻辑应为:

  • 先根据用户名查询用户的hashed_password字段;
  • 用BCrypt验证输入密码与存储的哈希是否匹配;
  • 兼容IPS定义的无效哈希规则(*0/*1)。

修改后的完整代码:

using BCrypt.Net;
using System.Data;
using MySql.Data.MySqlClient;

// ... 其他代码 ...

string server = "s570.use8.mysecurecloudhost.com";
string database = "nextgene_NGH";
string uid = "nextgene_NGH";
string password = "EXAMPLE PASSWORD";
string ssl = "None";

string connectionString = $"SERVER={server};DATABASE={database};UID={uid};PASSWORD={password};SSL Mode={ssl};";

// 先查询用户的哈希,而非直接对比
string SQL = "SELECT hashed_password FROM `core_members` WHERE name = @name;";
string storedHash = null;

try
{
    using (var connection = new MySqlConnection(connectionString))
    {
        connection.Open();
        using (var command = new MySqlCommand(SQL, connection))
        {
            command.Parameters.AddWithValue("@name", maskedTextBox1.Text);
            // 执行查询获取存储的哈希
            object result = command.ExecuteScalar();
            storedHash = result?.ToString();
        }
    }

    if (string.IsNullOrEmpty(storedHash))
    {
        MessageBox.Show("Login Failed: User not found.");
        return;
    }

    // 验证密码:BCrypt.Verify自动处理盐和工作因子,且为时间恒定对比
    bool isPasswordValid = BCrypt.Net.BCrypt.Verify(maskedTextBox2.Text, storedHash, true);

    // 兼容IPS的无效哈希规则
    if (storedHash == "*0" || storedHash == "*1" || !isPasswordValid)
    {
        MessageBox.Show("Login Failed.");
    }
    else
    {
        MessageBox.Show("Login Successful.");
    }
}
catch (Exception ex)
{
    MessageBox.Show(ex.Message);
}

4. 可选:自行实现PHP兼容的哈希对比

若不想依赖第三方库,可实现与PHPcompareHashes一致的时间恒定对比逻辑(仍需bcrypt哈希生成/验证,推荐用库):

private static bool CompareHashes(string expected, string provided)
{
    // 排除IPS定义的无效哈希
    if (string.IsNullOrEmpty(expected) || string.IsNullOrEmpty(provided) || 
        expected == "*0" || expected == "*1" || provided == "*0" || provided == "*1")
    {
        return false;
    }

    if (expected.Length != provided.Length)
    {
        return false;
    }

    int status = 0;
    for (int i = 0; i < expected.Length; i++)
    {
        status |= expected[i] ^ provided[i];
    }

    return status == 0;
}

内容的提问来源于stack exchange,提问作者Ryan Ellis

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.23 18:54:59