简体   繁体   中英

Trying to store password to database

i'm doing a test how hash and salt passwords. Well, i can add hash and salt password to the Database but i got stuck to store passwords from database. i have a simple Database:

                                Table
                               _______

                               ProvaHS
                               --------
                          (PK) LoginID   int 
                               UserName  nvarchar(50)
                               Password  nvarchar(50)
                               Salt      nvarchar(50)

So i create a form to add new record to the database with this code:

 public partial class Window1 : Window
{
    public Window1()
    {
        InitializeComponent();
    }

    #region SALT
    public static class PasswordCrypto
    {
        private static SHA1CryptoServiceProvider Hasher = new SHA1CryptoServiceProvider();
        //Private Hasher As New MD5CryptoServiceProvider()

        static internal string GetSalt(int saltSize)
        {
            byte[] buffer = new byte[saltSize + 1];
            RNGCryptoServiceProvider rng = new RNGCryptoServiceProvider();
            rng.GetBytes(buffer);
            return Convert.ToBase64String(buffer);
        }

        static internal string HashEncryptString(string s)
        {
            byte[] clearBytes = Encoding.UTF8.GetBytes(s);
            byte[] hashedBytes = Hasher.ComputeHash(clearBytes);
            return Convert.ToBase64String(hashedBytes);
        }

        static internal string HashEncryptStringWithSalt(string s, string salt)
        {
            return HashEncryptString(salt + s);
        }
    }
    #endregion

    private void GetSalt()
    {
        this.textBoxSalt.Text = PasswordCrypto.GetSalt(16);
    }

      private void GetSaltHash()
      {
          // It's how i salt and hash the password before to save it to the Database
          this.textBoxPassword.Text = PasswordCrypto.HashEncryptStringWithSalt(this.textBoxClear.Text, this.textBoxSalt.Text);
      }

    private void GetHash()
    {
        //Demo purposes -- this is an unsalted hash
        this.textBoxClear.Text = PasswordCrypto.HashEncryptString(this.textBoxPassword.Text);
    }

    private void Add(object sender, RoutedEventArgs e)
    {
        DataClasses1DataContext dc = new DataClasses1DataContext();

        try
        {
            if (textBoxUserName.Text.Length > 0)
            {
                ProvaH tab = new ProvaH();
                tab.UserName = textBoxUserName.Text;
                tab.Password = textBoxPassword.Text;
                tab.Salt = textBoxSalt.Text;
                dc.ProvaHs.InsertOnSubmit(tab);
                dc.SubmitChanges();

            }
        }
        catch (Exception ex)
        {

            MessageBox.Show("Error!!!");
        }

    }

    private void HashButton(object sender, RoutedEventArgs e)
    {
        GetHash();
    }

    private void SaltButton(object sender, RoutedEventArgs e)
    {
        GetSalt();
    }

    private void HashSaltButton(object sender, RoutedEventArgs e)
    {
        GetSaltHash();
    }

    private void Close_W(object sender, RoutedEventArgs e)
    {
        this.Close();
    }

}

}

  • with this method i can salt,hash and save password to the database..(following advices StackOverflow's member ) thanks..

Now i'm testing how store password from the database and here i got a trouble...

  public partial class Login : Window
{
    public Login()
    {
        InitializeComponent();
    }
    #region SALT
    public static class PasswordCrypto
    {
        private static SHA1CryptoServiceProvider Hasher = new SHA1CryptoServiceProvider();
        //Private Hasher As New MD5CryptoServiceProvider()

        static internal string GetSalt(int saltSize)
        {
            byte[] buffer = new byte[saltSize + 1];
            RNGCryptoServiceProvider rng = new RNGCryptoServiceProvider();
            rng.GetBytes(buffer);
            return Convert.ToBase64String(buffer);
        }

        static internal string HashEncryptString(string s)
        {
            byte[] clearBytes = Encoding.UTF8.GetBytes(s);
            byte[] hashedBytes = Hasher.ComputeHash(clearBytes);
            return Convert.ToBase64String(hashedBytes);
        }

        static internal string HashEncryptStringWithSalt(string s, string salt)
        {
            return HashEncryptString(salt + s);
        }
    }
    #endregion

    private void closs(object sender, RoutedEventArgs e)
    {
        this.Close();
    }


      public bool ValidateApplicationUser(string userName, string password)
      {

        bool OK = false;
          DataClasses1DataContext dc = new DataClasses1DataContext();

          object saltValue = from c in dc.ProvaHs where c.UserName == userName  select c.Salt;
          if (!(saltValue == System.DBNull.Value))
          {
              password = PasswordCrypto.HashEncryptStringWithSalt(passwordTextBox.Password, saltValue.ToString());

          }
          var query = from c in dc.ProvaHs where c.UserName == userName && c.Password == password select new { c.LoginID, c.UserName, c.Password };
          if (query.Count() != 0)
          {
              return true;
          }
       return false;
      }

    private void Confirm(object sender, RoutedEventArgs e)
    {
           bool authenticated = true;

        if (usernameTextBox.Text != "" && passwordTextBox.Password.ToString() != "") 
           {
               authenticated = ValidateApplicationUser(usernameTextBox.Text, passwordTextBox.Password.ToString());
           }
           if (!authenticated)
           {
               MessageBox.Show("Invalid login. Try again.");
           }
           else
           {
               MessageBox.Show("Aaaaahhhh.JOB DONE!!!!....");
           }
    }
}

when i debug the application i receive always an error at this code line: if (query.Count():= 0) in "query" = Empty?"Enumeration yielded no results" Do you have any suggest how work out this error and store password from database in my case? Thanks

Try:

public bool ValidateApplicationUser(string userName, string password)
{
  DataClasses1DataContext dc = new DataClasses1DataContext();

  var saltValue = dc.ProvaHs.Where(c => c.UserName == userName)
                            .Select(c => c.Salt)
                            .SingleOrDefault();

  if (saltValue == null) return false;

  password = PasswordCrypto.HashEncryptStringWithSalt(passwordTextBox.Password, saltValue.ToString());

  return dc.ProvaHs.Any(c => c.UserName == userName && c.Password == password);
}

Don't use SHA1. Use SHA256, real random salt, and lots (ie. 8000) of SHA256 iterations. Because SHA is designed for speed, but that means that dictionary attack is fast. There are also better ways, like scrypt algorithm. Or SRP protocol.

(Not strictly answering your question but I'll add it anyway)

Don't you want to just hex encode (not base64) the output?

public static string SHA256Hash(string Data)  
{  
    SHA256 sha = new SHA256Managed();  
    byte[] hash = sha.ComputeHash( Encoding.ASCII.GetBytes(Data) );  

    StringBuilder stringBuilder = new StringBuilder();  
    foreach( byte b in hash )   
    {  
        stringBuilder.AppendFormat("{0:x2}", b);  
    }  
    return stringBuilder.ToString();  
}

(That's SHA-2, just swap SHA256 for SHA1 and SHA256Managed with SHA1Managed).

Other snippet implementations here

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM