繁体   English   中英

试图将密码存储到数据库

[英]Trying to store password to database

我正在测试 hash 和 salt 密码。 好吧,我可以将 hash 和 salt 密码添加到数据库中,但我无法从数据库中存储密码。 我有一个简单的数据库:

                                Table
                               _______

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

因此,我使用以下代码创建了一个表单以将新记录添加到数据库中:

 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();
    }

}

}

  • 使用这种方法,我可以加盐,hash 并将密码保存到数据库..(遵循 StackOverflow 成员的建议)谢谢..

现在我正在测试如何从数据库中存储密码,在这里我遇到了麻烦......

  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!!!!....");
           }
    }
}

当我调试应用程序时,我总是在此代码行收到一个错误: if (query.Count():= 0) in "query" = Empty?"Enumeration yielded no results" 你有什么建议如何解决这个错误和在我的情况下从数据库存储密码? 谢谢

尝试:

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

不要使用 SHA1。 使用 SHA256、真正的随机盐和大量(即 8000)的 SHA256 迭代。 因为 SHA 是为速度而设计的,但这意味着字典攻击速度很快。 还有更好的方法,比如 scrypt 算法。 或 SRP 协议。

(没有严格回答你的问题,但我还是会添加它)

您不想对 output 进行十六进制编码(不是 base64)吗?

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();  
}

(即 SHA-2,只需将 SHA256 换成 SHA1,将 SHA256Managed 换成 SHA1Managed)。

此处的其他片段实现

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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