我一直在与这个逻辑以及如何获得HASH算法来检查从SQL Server数据库检索的条目是否与用户输入的条目相匹配。
下面的代码确实工作,我不能得到我的头周围是从SQL Server数据库检索的字段应该去的代码,以及它如何与用户输入的条目匹配。
下面的代码确实包含保存修改后的HASH条目的代码。
SQL Server数据库中的条目保存为Varbinary
'0xD94C0F10760D83BC35C0786C674B5F8F'
任何帮助都将非常感激。
string[] passwordargs = new string[] { "turkey", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat" };
//If no file name is specified, write usage text.
if (passwordargs.Length == 0)
{
Console.WriteLine(usageText);
}
else
{
string pwd1 = passwordargs[0];
// Create a byte array to hold the random value.
byte[] salt1 = new byte[8];
using (RNGCryptoServiceProvider rngCsp = new RNGCryptoServiceProvider())
{
// Fill the array with a random value.
rngCsp.GetBytes(salt1);
}
//data1 can be a string or contents of a file.
string data1 = "Some test data";
//The default iteration count is 1000 so the two methods use the same iteration count.
int myIterations = 1000;
try
{
Rfc2898DeriveBytes k1 = new Rfc2898DeriveBytes(pwd1, salt1, myIterations);
Rfc2898DeriveBytes k2 = new Rfc2898DeriveBytes(pwd1, salt1);
// Encrypt the data.
Aes encAlg = Aes.Create();
encAlg.Key = k1.GetBytes(16);
MemoryStream encryptionStream = new MemoryStream();
CryptoStream encrypt = new CryptoStream(encryptionStream, encAlg.CreateEncryptor(), CryptoStreamMode.Write);
byte[] utfD1 = new System.Text.UTF8Encoding(false).GetBytes(data1);
encrypt.Write(utfD1, 0, utfD1.Length);
encrypt.FlushFinalBlock();
encrypt.Close();
byte[] edata1 = encryptionStream.ToArray();
string encryptString = Convert.ToBase64String(edata1.ToArray());
string queryStmt = "UPDATE [dbo].[Staff] SET [MEMWORD] = (@Content) WHERE STAFF_ID=7";
using (SqlConnection _con = new SqlConnection(System.Configuration.ConfigurationManager.ConnectionStrings["AppDb"].ConnectionString))
using (SqlCommand _cmd = new SqlCommand(queryStmt, _con))
{
SqlParameter param = _cmd.Parameters.Add("@Content", SqlDbType.VarBinary);
param.Value = edata1;
_con.Open();
_cmd.ExecuteNonQuery();
_con.Close();
}
k1.Reset();
// Try to decrypt, thus showing it can be round-tripped.
Aes decAlg = Aes.Create();
decAlg.Key = k2.GetBytes(16);
decAlg.IV = encAlg.IV;
MemoryStream decryptionStreamBacking = new MemoryStream();
CryptoStream decrypt = new CryptoStream(decryptionStreamBacking, decAlg.CreateDecryptor(), CryptoStreamMode.Write);
decrypt.Write(edata1, 0, edata1.Length);
decrypt.Flush();
decrypt.Close();
k2.Reset();
string data2 = new UTF8Encoding(false).GetString(decryptionStreamBacking.ToArray());
if (!data1.Equals(data2))
{
Console.WriteLine("Error: The two values are not equal.");
}
else
{
Console.WriteLine("The two values are equal.");
Console.WriteLine("k1 iterations: {0}", k1.IterationCount);
Console.WriteLine("k2 iterations: {0}", k2.IterationCount);
}
}
catch (Exception e)
{
Console.WriteLine("Error: {0}", e);
string error = e.ToString();
}
}
你指的是
下面的代码可以工作…
if (!data1.Equals(data2))
是相等的,当你期望它是相等的?
在我的理解中,你设置了data1 = "Some test data"
,直到我们到达最后才会改变。
对于data2
,这需要更多的工作,但从上到下分解:
- 将
data1
存储在utfD1
中为UTF-8 bytearray ->byte[] utfD1 = new System.Text.UTF8Encoding(false).GetBytes(data1);
- 将
utfD1
写入流encrypt
(encryptionStream
是CryptoStream的底层流)->encrypt.Write(utfD1, 0, utfD1.Length);
- Write
encryptionStream
intedata1
字节数组->byte[] edata1 = encryptionStream.ToArray();
- 将
edata1
写入decryptionStreamBacking
(因为它是decrypt
的底层流)->decrypt.Write(edata1, 0, edata1.Length);
decryptionStreamBacking
解码UTF-8字节数组并存储在data2
->string data2 = new UTF8Encoding(false).GetString(decryptionStreamBacking.ToArray());
所以对我来说,它看起来像一个花哨的方式说string data2 = data1
和数据库是一个只写的场景。您只更新数据库中的一个值,但不从中读取任何内容。
感谢您的帮助和建议,我们现在已经完成了工作代码。
我们必须改变Byte [] salt1 = new Byte [8];来byte [] salt1 = new byte [] {0, 1, 2, 3, 4, 5, 6, 7};
否则每次的salt1都是不同的,这将创建一个不同的加密,这将不允许输入的密码与数据库中保存的密码配对。
谢谢大家的意见。
byte[] returned_Data;
string[] passwordargs = new string[] { "turkey", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat" };
//If no file name is specified, write usage text.
if (passwordargs.Length == 0)
{
Console.WriteLine(usageText);
}
else
{
string pwd1 = passwordargs[0];
byte[] salt1 = new byte[]{0,1 ,2, 3,4, 5,6, 7};
using (RNGCryptoServiceProvider rngCsp = new
RNGCryptoServiceProvider())
{
// Fill the array with a random value.
rngCsp.GetBytes(salt1);
}
//data1 can be a string or contents of a file.
string data1 = "Some test data";
//The default iteration count is 1000 so the two methods use the same iteration count.
int myIterations = 1000;
try
{
Rfc2898DeriveBytes k1 = new Rfc2898DeriveBytes(pwd1, salt1,myIterations);
Rfc2898DeriveBytes k2 = new Rfc2898DeriveBytes(pwd1, salt1);
// Encrypt the data.
Aes encAlg = Aes.Create();
encAlg.Key = k1.GetBytes(16);
MemoryStream encryptionStream = new MemoryStream();
CryptoStream encrypt = new CryptoStream(encryptionStream,
encAlg.CreateEncryptor(), CryptoStreamMode.Write);
byte[] utfD1 = new System.Text.UTF8Encoding(false).GetBytes(
data1);
encrypt.Write(utfD1, 0, utfD1.Length);
encrypt.FlushFinalBlock();
encrypt.Close();
byte[] edata1 = encryptionStream.ToArray();
string queryStmt = "UPDATE [dbo].[Staff] SET [PASSWORD] = (@Content) WHERE STAFF_ID=7";
using (SqlConnection _con = new SqlConnection(System.Configuration.ConfigurationManager.ConnectionStrings["Conn"].ConnectionString))
using (SqlCommand _cmd = new SqlCommand(queryStmt, _con))
{
SqlParameter param = _cmd.Parameters.Add("@Content", SqlDbType.VarBinary);
param.Value = edata1;
_con.Open();
_cmd.ExecuteNonQuery();
_con.Close();
}
using (SqlConnection sqlconnection = new SqlConnection(System.Configuration.ConfigurationManager.ConnectionStrings["Conn"].ConnectionString))
{
sqlconnection.Open();
string selectQuery = string.Format(@"Select [PASSWORD] From [dbo].[Staff] Where STAFF_ID={0}", 7);
SqlCommand selectCommand = new SqlCommand(selectQuery, sqlconnection);
SqlDataReader reader = selectCommand.ExecuteReader();
if (reader.Read())
{
returned_Data = (byte[])reader[0];
string strData = Encoding.UTF8.GetString(returned_Data);
Console.WriteLine(strData);
if(!edata1.SequenceEqual(returned_Data))
{
Console.WriteLine("Error: The two values are not equal.");
}
else
{
Console.WriteLine("The two values are equal.");
Console.WriteLine("k1 iterations: {0}", k1.IterationCount);
Console.WriteLine("k2 iterations: {0}", k2.IterationCount);
}
}
}