在WPF C#应用程序中散列密码

时间:2012-05-16 18:59:55

标签: c# mysql hash

我尝试创建一个远程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!");             
        } 
    }
 }

5 个答案:

答案 0 :(得分: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上将数据存储在数据库中的精彩文章......

The Art & Science of Storing Passwords

答案 1 :(得分: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的值。

无论其...

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

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
    }
 }

答案 2 :(得分:0)

创建一个为您完成的功能:

这是asp.NET

public static string PasswordHasher(string Password)
{
return FormsAuthentication.HashPasswordForStoringInConfigFile(Password,     
System.Web.Configuration.FormsAuthPasswordFormat.SHA1);
}

答案 3 :(得分:0)

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

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

所以它实际上没关系,你会破坏用户密码还是不会 - 任何人都可以访问你的系统。

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

那么哈什呢。

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

如果要在数据库中存储密码哈希,则应研究ASP.NET成员资格提供程序中构建的数据库方案。

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

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

答案 4 :(得分:0)

.Net内置了对MD5哈希算法和许多其他哈希算法的支持。在Microsoft网站上有一个很好的例子: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