WPF C# 应用程序中的哈希密码
本文关键字:哈希 密码 应用程序 WPF | 更新日期: 2023-09-27 18:34:18
>我尝试创建一个远程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!");
}
}
}
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上将密码存储在数据库中的精彩文章......
存储密码的艺术与科学
您将使用哈希算法提供程序,例如 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);
现在,您可以在查询中使用哈希密码的值。
然而。。。
您还应考虑为整个应用程序生成一个盐值,或者更好的是,为每个用户生成一个盐值。您需要在表中有一列来存储它,并在每次更改密码时为每个用户随机生成它。然后,您将使用类似以下内容来创建散列密码:
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
}
}
创建一个函数来为你做这件事:
这是 asp.NET
public static string PasswordHasher(string Password)
{
return FormsAuthentication.HashPasswordForStoringInConfigFile(Password,
System.Web.Configuration.FormsAuthPasswordFormat.SHA1);
}
相信您将能够使用此代码进行安全的身份验证。
首先,您将密码存储在代码中。因此,任何人都可以使用Reflector或任何其他.NET解码器将密码提取到数据库。然后,有了完整的连接字符串,任何人都可以连接到您的数据库并破坏它(例如,窃取所有用户密码(。即使您使用模糊处理工具,仍然可以从应用程序中提取此字符串。
所以这实际上并不重要,你会散列用户密码还是不会 - 任何人都可以访问你的系统。
执行密码验证的更安全方法是创建多疲系统,因此WPF应用程序不能直接访问数据库,它用户应用程序服务器对数据执行任何操作。对于通信,您可以使用 Web 服务 WCF。数据库的连接字符串将仅存储在应用程序服务器中。
现在哈希呢。
你必须找出为什么要使用哈希。您可以使用哈希将其存储在数据库中(因此清除密码不会存储在任何地方(。您可以使用哈希通过网络发送密码,因此即使消息被拦截,也没有人会发现明确的密码(。或者,您可以同时使用哈希。
如果要将密码哈希存储在数据库中,则应研究 ASP.NET 成员资格提供程序中内置的数据库方案。
根据您选择的选项,您可以实现实际的密码验证。
实际上,如何计算哈希并不重要。它只需要足够强大的哈希算法,例如 .NET Framework 中的 SHA512。
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