【问题标题】:Error when converting from base 64 string从 base 64 字符串转换时出错
【发布时间】:2020-03-05 10:50:48
【问题描述】:

我正在尝试加密和解密存储在 SQL 中的密码。解码时出现错误输入不是有效的 Base-64 字符串,因为它包含非 base 64 字符、两个以上的填充字符或填充字符中的非法字符。在 System.Convert.FromBase64_Decode。

解密代码:

string userEmail = Email1.Text;
string userPass = passW.Text;
SqlConnection sqlcon = new SqlConnection("My connection")
string query = "Select * from users Where email= '" + userEmail + "'";
SqlDataAdapter sda = new SqlDataAdapter(query, sqlcon);
DataTable dtbl = new DataTable()
sda.Fill(dtbl);
if (dtbl.Rows.Count == 1)
{
    string savedPasswordHash = dtbl.Rows[0][1].ToString();
    savedPasswordHash.Replace("-", "");
    byte[] hashBytes = Convert.FromBase64String(savedPasswordHash);
    byte[] salt = new byte[16];
    Array.Copy(hashBytes, 0, salt, 0, 16);
    var pbkdf2 = new Rfc2898DeriveBytes(userPass, salt, 10000);
    byte[] hash = pbkdf2.GetBytes(20);
    int ok = 1;
    for (int i = 0; i < 20; i++)
        if (hashBytes[i + 16] != hash[i])
            ok = 0;
            if (ok == 1) //good creds & redirect

加密代码:

byte[] salt1;
new RNGCryptoServiceProvider().GetBytes(salt1 = new byte[16]);
var pbkdf21 = new Rfc2898DeriveBytes(EmailTextBox.Text, salt1, 10000); 

byte[] hash1 = pbkdf21.GetBytes(20);
byte[] hashBytes1 = new byte[36];

Array.Copy(salt1, 0, hashBytes1, 0, 16);
Array.Copy(hash1, 0, hashBytes1, 16, 20);

string savedPasswordHash1 = Convert.ToBase64String(hashBytes1);
string commString = $"UPDATE users SET NewPassword = ('{savedPasswordHash1}') where Email = ('{email2}')";
using (SqlConnection connect = new SqlConnection(constring))
{
    using (SqlCommand comm = new SqlCommand())
    {
        comm.Connection = connect;
        comm.CommandText = commString;
        connect.Open();
        comm.ExecuteNonQuery();
        connect.Close();
    } 

列的数据类型是nvarchar

【问题讨论】:

  • 请同时显示插入部分的代码。还要检查并给出数据库中密码字段的数据类型。您可能想要更多地隔离您的代码,因此请查看 savedPasswordHash 中的实际内容
  • 这看起来不太对...Select后面不应该有一个列列表吗? string query = "Select from users Where email= '" + userEmail + "'";
  • OT 请使用参数而不是将值构建到 SQL 字符串中
  • @Emad 我在 savedPasswordHash 字符串中得到 7408207-16186516-9228325
  • SavedPasswordHash.Replace 没有任何作用

标签: c# sql asp.net


【解决方案1】:

好的,问题出在您的 SQL 代码中。你不应该像这样在查询中添加值。这会带来巨大的 SQL 注入攻击风险以及您面临的问题。

base64 字符串可能包含不打算进入查询字符串的字符。

所以像这样改变加密:

string commString = "UPDATE users SET NewPassword = @PasswordHash where Email = @Email";
using (SqlConnection connect = new SqlConnection(constring))
{
    using (SqlCommand comm = new SqlCommand())
    {
        comm.Connection = connect;
        comm.CommandText = commString;
        comm.Parameters.AddWithValue("PasswordHash", savedPasswordHash1);
        comm.Parameters.AddWithValue("Email", email2);
        connect.Open();
        comm.ExecuteNonQuery();
        connect.Close();
    } 
}

您也可以简化命令创建,但我不想更改两件事。您可以稍后修复它。

--编辑--

来回后很明显问题出在解密而不是加密部分。你按照我上面说的去做,否则你的代码有严重的危险。

string savedPasswordHash = dtbl.Rows[0][27].ToString(); //Change 1 to 27

同时删除下一行

//savedPasswordHash.Replace("-", ""); (Remove)

【讨论】:

  • 我的 int ok =1 现在一直等于 0。我忽略了什么吗?
猜你喜欢
  • 2015-08-09
  • 2017-12-04
  • 1970-01-01
  • 2018-01-22
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-07-09
  • 2022-01-20
相关资源
最近更新 更多