【发布时间】:2021-08-17 06:48:20
【问题描述】:
我是一个相当新的开发人员,所以请耐心等待,这让我很头疼。
我一直在尝试将我正在开发的 Winforms 应用程序的密码以加密格式存储在数据库中。首次打开应用时有登录和注册界面。
我已经设法加密了注册期间提供的密码,它在数据库中不是明文,我为此使用了一个类Cryptography。但是,当我尝试解密密码以授予用户对应用程序的访问权限时,我收到异常未处理错误:
输入不是有效的 Base-64 字符串,因为它包含非 base-64 字符、两个以上的填充字符或填充字符中的非法字符。
有没有办法解决这个问题?我想不通。
进行加密的代码:
public static string Encrypt(string encryptString)
{
string EncryptionKey = "djknh46hdkkjsdvvjjsijeykskerfubb1906234575";
byte[] clearBytes = Encoding.Unicode.GetBytes(encryptString);
using (Aes encryptor = Aes.Create())
{
Rfc2898DeriveBytes pdb = new Rfc2898DeriveBytes(EncryptionKey, new byte[] {
0x49, 0x76, 0x61, 0x6e, 0x20, 0x4d, 0x65, 0x64, 0x76, 0x65, 0x64, 0x65, 0x76});
encryptor.Key = pdb.GetBytes(32);
encryptor.IV = pdb.GetBytes(16);
using (MemoryStream ms = new MemoryStream())
{
using (CryptoStream cs = new CryptoStream(ms, encryptor.CreateEncryptor(),
CryptoStreamMode.Write))
{
cs.Write(clearBytes, 0, clearBytes.Length);
cs.Close();
}
encryptString = Convert.ToBase64String(ms.ToArray());
}
}
return encryptString;
}
应该进行解密的代码:
public static string Decrypt(string cipherText)
{
string EncryptionKey = "djknh46hdkkjsdvvjjsijeykskerfubb1906234575";
cipherText = cipherText.Replace(" ", "+");
byte[] cipherBytes = Convert.FromBase64String(cipherText);
using (Aes encryptor = Aes.Create())
{
Rfc2898DeriveBytes pdb = new Rfc2898DeriveBytes(EncryptionKey, new byte[] {
0x49, 0x76, 0x61, 0x6e, 0x20, 0x4d, 0x65, 0x64, 0x76, 0x65, 0x64, 0x65, 0x76});
encryptor.Key = pdb.GetBytes(32);
encryptor.IV = pdb.GetBytes(16);
using (MemoryStream ms = new MemoryStream())
{
using (CryptoStream cs = new CryptoStream(ms, encryptor.CreateDecryptor(),
CryptoStreamMode.Write))
{
cs.Write(cipherBytes, 0, cipherBytes.Length);
cs.Close();
}
cipherText = Encoding.Unicode.GetString(ms.ToArray());
}
}
return cipherText;
}
这样做的代码应该从数据库中验证密码:
string Password = "";
bool IsExist = false;
SqlCommand command = new SqlCommand("select * from LibraryUser where UserName='" +
txtUsernameLogin.Text + "'", connection1);
SqlDataReader dataReader = command.ExecuteReader();
if (dataReader.Read())
{
Password = dataReader.GetString(4);
IsExist = true;
}
connection1.Close();
if (IsExist)
{
if (Cryptography.Decrypt(Password).Equals(txtPasswordLogin.Text))
{
this.Hide();
new LibraryForm().Show();
}
else
{
MessageBox.Show("The password you have entered is incorrect, please try again.",
"Incorrect Password", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
else
{
MessageBox.Show("Please enter the valid credentials.", "Error",
MessageBoxButtons.OK, MessageBoxIcon.Error);
}
感谢任何人提供的任何帮助,在此先感谢。
【问题讨论】:
-
您不需要解密密码,因为它们应该只存储为加盐哈希。
-
这不是最佳实践。始终使用如上所述的单向加密,然后以相同的方式加密用户输入以进行匹配。
-
原谅我,什么意思?这是否意味着我应该删除解密的代码?什么是盐渍哈希?我该如何使用它们?
-
是的,从不解密。谷歌将帮助您解决第二个问题。密码管理方面肯定有很多很好的例子。
-
SQL Injection alert - 您应该不将您的 SQL 语句连接在一起 - 使用 参数化查询 来避免 SQL 注入 - 查看 Little Bobby Tables
标签: c# sql-server encryption