【问题标题】:How to Store and retrieve Salt from and into a database?如何在数据库中存储和检索 Salt?
【发布时间】:2020-07-23 10:01:27
【问题描述】:

我已经设法编写了一组方法来获取密码、添加盐并将盐和散列密码存储在数据库中。 但是当我尝试检索和打印盐时,它会打印System.byte[] 而不是盐字符串。我认为方法的返回类型存在问题。这是我的方法,

class HashSalt
    {

        private readonly int num_of_iterations;

        // --- constructor to initialize num_of_iterations
        public HashSalt(int numOfIterations)
        {
            num_of_iterations = numOfIterations;
        }

        // --- Generate Salt ---
        public string  generateSalt()
        {
            var salt = new byte[32];

            var randomProvider = new RNGCryptoServiceProvider();
            randomProvider.GetBytes(salt);

            return Convert.ToBase64String(salt);        // returns salt as a string
        }

        // --- converts salt string into byte[]
        public byte[] saltToByte(string salt)
        {
            var byteSalt = Convert.FromBase64String(salt);
            return byteSalt;
        }

        // --- Generate hash of(pass+salt) ---
        public string generateHash(string password, byte[] salt)
        {

            var rfc2898 = new Rfc2898DeriveBytes(password, salt, num_of_iterations);

            var Password = rfc2898.GetBytes(32);    // gives 32 byte encoded password

            return Convert.ToBase64String(Password);    // returns hash
        }
    }

数据库结构

用于保存到数据库的代码

DbHandler db = new DbHandler();
                MySqlCommand cmd = new MySqlCommand("INSERT INTO `student`(`indexno`,`firstname`,`lastname`,`address`,`gender`,`dob`,`email`,`faculty`,`mobile`,`password`,`salt`)VALUES(@index, @firstname, @lastname, @address, @gender, @dob, @email, @faculty, @mobile, @password, @salt);", db.getConnection());


                var salt = hashSalt.generateSalt();  // generates random salt type string
                var byteSalt = hashSalt.saltToByte(salt);   // gets byte[] from salt string

                cmd.Parameters.Add("@index", MySqlDbType.VarChar).Value = txtindex.Text;
                cmd.Parameters.Add("@firstname", MySqlDbType.VarChar).Value = txtfname.Text;
                cmd.Parameters.Add("@lastname", MySqlDbType.VarChar).Value = txtlname.Text;
                cmd.Parameters.Add("@address", MySqlDbType.VarChar).Value = txtaddress.Text;
                cmd.Parameters.Add("@gender", MySqlDbType.VarChar).Value = getGender();
                cmd.Parameters.Add("@dob", MySqlDbType.Date).Value = dateDob.Value.Date;
                cmd.Parameters.Add("@email", MySqlDbType.VarChar).Value = txtemail.Text;
                cmd.Parameters.Add("@faculty", MySqlDbType.VarChar).Value = cmbfaculty.GetItemText(cmbfaculty.SelectedItem);
                cmd.Parameters.Add("@mobile", MySqlDbType.VarChar).Value = txtmobile.Text;
                cmd.Parameters.Add("@password", MySqlDbType.VarChar).Value = hashSalt.generateHash(txtpassword.Text, byteSalt); // get (password+salt) hashed from db 
                cmd.Parameters.Add("@salt", MySqlDbType.VarBinary).Value = salt;

                db.openConnection();    // open connection
                // execute query
                if (cmd.ExecuteNonQuery() == 1)
                {
                    MessageBox.Show("Record added!", "Success!", MessageBoxButtons.OK, MessageBoxIcon.Information);
                }
                else
                {
                    MessageBox.Show("Failed!, please retry", "Error!", MessageBoxButtons.OK, MessageBoxIcon.Error);
                }
                db.openConnection();    // close connection

希望能解决这个问题。

【问题讨论】:

    标签: c# .net hash salt


    【解决方案1】:

    但是当我尝试检索和打印盐时,它会打印 System.byte[] 而不是盐字符串。希望能解决这个问题。

    如果没有给出字符串,WriteLine 和大多数类似的代码将获取一个对象并在其上调用 ToString()

    ToString() 的默认实现将类名作为字符串返回 - 在您的情况下为 System.byte[] - 然后可以打印。类需要覆盖ToString(),如果他们想要一些对调试更有用的东西。例如,字符串会返回自身或自身的副本(我认为是前者,但我必须查看代码)。

    也没有自动尝试迭代数组或其他集合。它只会自动打印类名。如果要打印集合的内容,则必须手动迭代它 - 并且可能递归地 - 添加适当的分隔符和注释字符。对于这种情况,应该使用一个简单的 foreach。但是我不确定你想如何在这里将每个字节转换为字符串或字符。通常您会将一个字节打印为 2 位十六进制值。

    【讨论】:

    • 感谢提示我找到了解决方案:) 覆盖部分已经由 generateSalt() 方法完成,问题在于 salt 存储在数据库中,我所要做的就是将 datatype 更改为 varchar
    【解决方案2】:

    找到了,问题出在数据库中salt列datatype设置为varBinary,但是返回的类型是方法 generateSalt()string 并且该字符串被发送以存储到数据库中。所以我所要做的就是将数据库中的盐列的数据类型更改为varchar

    【讨论】:

      猜你喜欢
      • 2017-12-30
      • 2011-03-21
      • 2017-04-03
      • 1970-01-01
      • 1970-01-01
      • 2011-12-30
      • 1970-01-01
      • 1970-01-01
      • 2013-06-17
      相关资源
      最近更新 更多