0

我试图创建一个远程 MySQL 数据库并将其链接到 WPF 应用程序。我设法做到了,但论坛的用户建议我对我的密码进行哈希处理,因为它很容易被 SQL 注入。我的问题是有人知道如何根据该代码创建散列密码:

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using MySql.Data.MySqlClient;

namespace ECBSRecruitmentAgencySoftware
{
    public partial class LogIn : Form
    {
        public LogIn()
        {
            InitializeComponent();
        }  

        public bool tryLogin(string username , string password)
        {
             MySqlConnection con = new MySqlConnection("host=aaaaaaaa.baaadsg;user=saaaaaak;password=2333333336;database=soaaaaaaaa2;");
             MySqlCommand cmd = new MySqlCommand("Select * FROM niki WHERE user_name = `" + username + "` AND user_password = `" + password + "`;");
             cmd.Connection = con;
             con.Open();
             MySqlDataReader reader = cmd.ExecuteReader();
             if (reader.Read() != false)
             {
                 if (reader.IsDBNull(0) == true)
                 {
                     cmd.Connection.Close();
                     reader.Dispose();
                     cmd.Dispose();
                     return false;
                 }
                 else
                 {
                     cmd.Connection.Close();
                     reader.Dispose();
                     cmd.Dispose();
                     return true;
                  }
             }
             else 
             {
                 return false;
             }
        }

        private void button1_Click(object sender, EventArgs e)
        {
            if (tryLogin(user.Text, pass.Text) == true)
            {
                MainScreen F2 = new MainScreen();
                F2.Show();
                this.Hide();
            }            
            else 
                MessageBox.Show("Wrong details!");             
        } 
    }
 }
4

5 回答 5

2

.NET 支持多种加密哈希,包括 MD5 和 SHA,因此使用ComputeHash这些类的方法很容易对您的密码进行哈希处理......

下面是一个使用 MD5 对文件进行哈希处理的简单示例,可以轻松地将其转换为生成密码哈希:

        using (var md5 = new MD5CryptoServiceProvider())
        {
            var buffer = md5.ComputeHash(File.ReadAllBytes(filename));
            var sb = new StringBuilder();
            for (var i = 0; i < buffer.Length; i++)
            {
                sb.Append(buffer[i].ToString("x2"));
            }
            return sb.ToString();
        }

别忘了给你的哈希加盐……

实际上,最好只是阅读这篇关于在 CP 上将密码存储在数据库中的精彩文章......

存储密码的艺术与科学

于 2012-05-16T19:17:51.813 回答
1

您将使用散列算法提供程序,例如 SHA256。

var hasher = new SHA256Managed();
var unhashed = System.Text.Encoding.Unicode.GetBytes(password);
var hashed = hasher.ComputeHash(unhashedPassword);

现在,为了在 SQL 查询中进行存储和比较,您需要将字节转换为字符串表示形式,例如 Base64Encoded。

var hashedPassword = Convert.ToBase64String(hashed);

现在您可以在查询中使用 hashedPassword 的值。

然而...

您还应该考虑为整个应用程序生成一个盐值,或者更好的是,为每个用户生成一个盐值。您需要表中的一列来存储它,并在每次更改密码时为每个用户随机生成它。然后你会使用这样的东西来创建散列密码:

static byte[] GenerateSaltedHash(string plainText, string salt)
{
HashAlgorithm algorithm = new SHA256Managed();

byte[] plainTextBytes = System.Text.Encoding.Unicode.GetBytes(plainText);
byte[] saltBytes = Convert.FromBase64String(salt);

byte[] plainTextWithSaltBytes = new byte[plainTextBytes.Length + saltBytes.Length];
salt.CopyTo(plainTextWithSaltBytes, 0);
plainText.CopyTo(plainTextWithSaltBytes, salt.Length); 

byte[] hash = algorithm.ComputeHash(plainTextWithSaltBytes);

return hash;
}

把它们放在一起...

// omitted

namespace ECBSRecruitmentAgencySoftware
{
    public partial class LogIn : Form
    {
        // omitted


    static byte[] GenerateSaltedHash(string plainText, string salt)
    {
       HashAlgorithm algorithm = new SHA256Managed();

       byte[] plainTextBytes = System.Text.Encoding.Unicode.GetBytes(plainText);
       byte[] saltBytes = Convert.FromBase64String(salt);

       byte[] plainTextWithSaltBytes = new byte[plainTextBytes.Length + saltBytes.Length];
       salt.CopyTo(plainTextWithSaltBytes, 0);
       plainText.CopyTo(plainTextWithSaltBytes, salt.Length); 

       byte[] hash = algorithm.ComputeHash(plainTextWithSaltBytes);

       return hash;
    }

        public bool tryLogin(string username , string password)
        {
             using (var con = new MySqlConnection("host=aaaaaaaa.baaadsg;user=saaaaaak;password=2333333336;database=soaaaaaaaa2;"))
             {
                 con.Open();

                 var salt = string.Empty;

                 using (var cmd = new MySqlCommand("Select salt From niki where user_name = @username"))
                 {
                     cmd.Parameters.AddWithValue("@username", username);

                     salt = cmd.ExecuteScalar() as string;
                 }

                 if (string.IsNullOrEmpty(salt)) return false;

                 var hashedPassword = GenerateSaltedHash(password, salt);

                 using (var cmd = new MySqlCommand("Select * FROM niki WHERE user_name = @username and user_password = @password"))
                 {
                    cmd.Parameters.AddWithValue("@username", username);
                    cmd.Parameters.AddWithValue("@password", hashedPassword);

                    using (var reader = cmd.ExecuteReader())
                    {
                         return reader.Read();
                    }
                 }
             }
        }

        // omitted
    }
 }
于 2012-05-16T19:17:11.517 回答
0

我不相信您将能够使用此代码进行安全的身份验证。

首先,您将密码存储到您的代码中的数据库中。因此,任何人都可以使用 Reflector 或任何其他 .NET 反编译器将密码提取到数据库。然后,拥有完整的连接字符串,任何人都可以连接到您的数据库并破坏它(例如,窃取所有用户密码)。即使您使用混淆工具,仍然可以从您的应用程序中提取此字符串。

所以实际上并不重要,你是否会散列用户密码 - 任何人都可以访问你的系统。

执行密码验证的更安全的方法是创建多层系统,因此 WPF 应用程序不能直接访问数据库,它用户应用程序服务器对数据执行任何操作。对于通信,您可以使用 Web 服务、WCF。到您的数据库的连接字符串将仅存储在应用程序服务器中。

现在哈希呢。

您必须找出为什么要使用哈希。您可以使用哈希将其存储在数据库中(因此明确的密码不会存储在任何地方)。您可以使用哈希通过网络发送密码,因此即使消息被截获,也没有人会发现清晰的密码)。或者您可以同时使用哈希。

如果您将密码哈希存储在数据库中,您应该研究在 ASP.NET 会员提供程序中构建的数据库方案。

根据您选择的选项,您可以实施实际的密码验证。

实际上,如何计算哈希并不重要。它只需要足够强大的哈希算法,例如 .NET Framework 中内置的 SHA512。

于 2012-05-16T19:32:39.793 回答
0

创建一个函数来为你做这件事:

这是 asp.NET

public static string PasswordHasher(string Password)
{
return FormsAuthentication.HashPasswordForStoringInConfigFile(Password,     
System.Web.Configuration.FormsAuthPasswordFormat.SHA1);
}
于 2012-05-16T19:11:44.747 回答
0

.Net 内置了对 MD5 哈希算法和许多其他哈希算法的支持。微软网站上有一个很好的例子:https ://msdn.microsoft.com/en-us/library/system.security.cryptography.md5(v=vs.110).aspx#Examples 。

要了解有关如何以及为什么需要散列的更多信息,您可以查看此站点:https ://www.codeproject.com/Articles/704865/Salted-Password-Hashing-Doing-it-Right

于 2018-01-03T05:10:49.883 回答