c# - 尝试将密码存储到数据库

标签 c# .net database linq-to-sql

我正在测试如何使用哈希和盐密码。 好吧,我可以将哈希和盐密码添加到数据库,但我无法从数据库存储密码。 我有一个简单的数据库:

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

}

}

  • 通过这种方法,我可以对密码进行加盐、哈希处理并将其保存到数据库中。(遵循 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 :"枚举没有产生结果" 在我的情况下,您有什么建议如何解决此错误并从数据库存储密码吗? 谢谢

最佳答案

尝试:

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

关于c# - 尝试将密码存储到数据库,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/585320/

相关文章:

php - PDO MySQL 检查数据库是否存在

c# - 如何将 ASP.NET Framework 配置迁移到 ASP.NET Core?

c++ - 如何在qt中修复 "No query Unable to fetch row"

c# - SQLite。修复 sqlite-net-wp8 项目依赖项

C# protobuf-net - 默认值覆盖来自 protobuf 数据的值

c# - 为什么覆盖 Parallel.foreach 循环的 .NET 单元测试依赖于硬件?

c# - .NET Core 运行时向后兼容性

python - 如何在 Django 中过滤具有多对多关系的对象

c# - 字段 'LogicalName' 缺少必需的成员 'Target'

c# - 在 C# WebBrowser 中加载本地 HTML 文件