c# - 从 base 64 字符串转换时出错
问题描述
我正在尝试加密和解密存储在 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
解决方案
好的,问题出在您的 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)
推荐阅读
- reactjs - redux saga 正在返回 SagaTestError:检查 api 调用时未满足期望
- javascript - 在没有库的 HTML 中附加 JavaScript 对象
- javascript - 加载内容 Ajax 不会丢失最后的内容
- java - 如何将线条绘制为组件?
- selenium - 真正的 chrome 浏览器和 chromedriver 的区别?
- git - 使用 fetch 代替带有 rebase 标志的 magit pull 等效于什么?
- python - 当许多.py文件导入重复包时,如何保持规范的软件工程?
- java - 从 String 获取 JSON 名称
- javascript - 显示 blob 2 次
- arrays - Julia 1.4.1 中发现的不稳定性:重复的数组构造导致下一个“print”或“println”调用随机中断