2012-05-16 3 views
0

Я попытался создать удаленную базу данных MySQL и связать ее с приложением WPF. Мне это удается, но я был предупрежден пользователями из форума, чтобы хэш-пароль, потому что его можно легко вводить SQL. Мой вопрос кто-нибудь знает, как я могу создать хэш пароля на основе этого кода:Хеширование пароля в приложении WPF C#

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

Вы не должны построить вашу команду SQL с помощью concatinating строки, параметры использования вместо этого. Вы можете использовать класс SHA1CryptoServiceProvider для создания хешированных значений. – Mithrandir

+0

Также используйте команду «using» для одноразовых экземпляров (например: MySQLConnection, MySQLCommand) для безопасного кода. –

+0

Вы должны использовать параметризованный запрос, чтобы убедиться, что вы не уязвимы для SQL-инъекции. Вы должны использовать все свои пароли, чтобы кто-нибудь когда-либо обращался к вашей базе данных (даже администратору сайта, то есть вам) по какой-либо причине, они будут видеть только бессмысленные хэши, а не фактические пароли открытого текста. Это две очень четкие меры безопасности, которые защищают от различных проблем. Вы должны реализовать оба из них. – Servy

ответ

0

Создать функцию, чтобы сделать это для вас:

Это asp.NET

public static string PasswordHasher(string Password) 
{ 
return FormsAuthentication.HashPasswordForStoringInConfigFile(Password,  
System.Web.Configuration.FormsAuthPasswordFormat.SHA1); 
} 
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 
    } 
} 
+0

Я попробовал ваш код, но кажется, что это дает мне эти ошибки: Ошибка: нет перегрузки метода «Copy To» не принимает 2 аргумента Исключения: System.ArgumentNullException System.ArgumentOutOfRangeException –

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

+0

+1 за ссылку, потому что OP даже не знает * почему * ему нужно хешировать пароли, и ссылка действительно помогает объяснить это. – Servy

0

Я не верю, что вы сможете сделать безопасный способ аутентификации с помощью этого кода.

Прежде всего, вы храните пароль в своей базе данных в своем коде. Поэтому любой может использовать Reflector или любой другой декомпилиратор .NET для извлечения пароля в базу данных. Затем, имея полную строку соединения, любой может подключиться к вашей базе данных и скомпрометировать ее (например, украсть все пользовательские пароли). Даже если вы используете инструменты обфускации, все равно можно извлечь эту строку из вашего приложения.

Таким образом, на самом деле это не имеет значения, вы будете использовать хэш-пароль пользователя или нет - любой может получить доступ к вашей системе.

Более безопасный способ проверки пароля - создание многопользовательской системы, поэтому приложение WPF не может напрямую обращаться к базе данных, а пользователям Сервер приложений выполнять любые операции с данными. Для связи вы можете использовать веб-службы WCF. Строка подключения к вашей базе данных будет храниться только на сервере приложений.

Теперь как насчет хэшей.

Вы должны выяснить, почему вы хотите использовать хэш. Вы можете использовать хеш для хранения его в базе данных (так что чистый пароль не хранится нигде). Вы можете использовать хэш для отправки пароля по сети, поэтому даже если сообщение перехвачено, никто не узнает четкий пароль). Или вы можете использовать хэш для обоих.

Если вы храните хэш пароля в базе данных, вам следует изучить схему базы данных для сборки в провайдере членства ASP.NET.

Исходя из выбранного вами варианта, вы можете реализовать фактическую проверку пароля.

На самом деле, не имеет значения, как вы будете вычислять хэш. Это должен быть достаточно сильный алгоритм хеширования, например SHA512, который встроен в .NET Framework.

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

Смежные вопросы