我使用下面的方法对密码进行加密和散列
public string CreateSalt(int size)
{
var rng = new System.Security.Cryptography.RNGCryptoServiceProvider();
var buff = new byte[size];
rng.GetBytes(buff);
return Convert.ToBase64String(buff);
}
public string GenerateSHA256Hash(String input, String salt)
{
byte[] bytes = System.Text.Encoding.UTF8.GetBytes(input + salt);
System.Security.Cryptography.SHA256Managed sha256hashstring =
new System.Security.Cryptography.SHA256Managed();
byte[] hash = sha256hashstring.ComputeHash(bytes);
return Convert.ToBase64String(hash);
}
public void Submit1_click(object sender, EventArgs r)
{
try
{
String salt = CreateSalt(10);
String hashedpassword = GenerateSHA256Hash(password1.Text, salt);
string MyConString = "SERVER=localhost;DATABASE=mydb;UID=root;PASSWORD=abc123;";
MySqlConnection connection = new MySqlConnection(MyConString);
string cmdText = "INSERT INTO authentication(agentlogin ,password ,question ,answer)VALUES ( @login, @pwd, @question, @answer)";
MySqlCommand cmd = new MySqlCommand(cmdText, connection);
cmd.Parameters.AddWithValue("@login", labeluname.Text);
cmd.Parameters.AddWithValue("@pwd", hashedpassword);
cmd.Parameters.AddWithValue("@question", ddlquestion.Text);
cmd.Parameters.AddWithValue("@answer", txtanswer.Text);
connection.Open();
int result = cmd.ExecuteNonQuery();
connection.Close();
lblmsg.Text = "Registered succesfully";
lblmsg.ForeColor = System.Drawing.Color.Green;
Response.Redirect("index.aspx");
}
catch (Exception)
{
Console.Write("not entered");
lblmsg.Text = "Registration failed!";
lblmsg.ForeColor = System.Drawing.Color.Red;
Response.Redirect("index.aspx");
}
}
所以我从上面得到了完全加密的密码,但是现在我不能使用输入的密码登录。如何在登录时取消密码?我想我可以使用相同的加密方法来解压它,但是salting不会返回相同的值。下面是验证页面上的代码
public string GenerateSHA256Hash(String input)
{
byte[] bytes = System.Text.Encoding.UTF8.GetBytes(input);
System.Security.Cryptography.SHA256Managed sha256hashstring =
new System.Security.Cryptography.SHA256Managed();
byte[] hash = sha256hashstring.ComputeHash(bytes);
return Convert.ToBase64String(hash);
}
public void Login_click(object sender, EventArgs r)
{
String hashedpassword = GenerateSHA256Hash(txtpassword.Text);
string MyConString = ConfigurationManager.ConnectionStrings["connStr"].ConnectionString;
MySqlConnection con = new MySqlConnection(MyConString);
MySqlCommand cmd = new MySqlCommand("select * from authentication where agentlogin=@username and password=@word", con);
cmd.Parameters.AddWithValue("@username", txtusername.Text);
cmd.Parameters.AddWithValue("@word", hashedpassword);
MySqlDataAdapter sda = new MySqlDataAdapter(cmd);
DataTable dt = new DataTable();
sda.Fill(dt);
con.Open();
int i = cmd.ExecuteNonQuery();
con.Close();
if (dt.Rows.Count > 0)
{
Session["id"] = txtusername.Text;
Response.Redirect("calendar.aspx");
Session.RemoveAll();
}
else
{
lblmsg.Text = "Credential doesn't match!";
lblmsg.ForeColor = System.Drawing.Color.Red;
}
}
3条答案
按热度按时间5rgfhyps1#
我想我可以使用相同的加密方法来解压它,但是salting不会返回相同的值。
你的意思是你通过salting机制发送了一次salted密码,希望得到一个未修改的清晰密码?这没有任何意义。
所以,你添加了一个密码并保存在某个地方。你现在要做的是,当一个用户输入他的密码,你盐这个新密码,并得到一个盐密码。然后把这个新的和旧的核对一下;如果他们匹配,那就是正确的密码。
igetnqfo2#
在将盐添加到密码并对其进行哈希运算之前,必须先存储盐。
因此,当someme尝试登录时,您将密码与存储的salt连接起来,然后您可以对其进行散列,并将其与base中现有的散列进行比较。
所以您的用户表至少应该有以下3列:username、hashedpassword和salt
更详细的说明:哈希函数是确定性的,但不可逆,因此当用户第一次创建密码时:
你产生了一种盐
将密码和salt连接起来
您可以散列密码和salt串联的结果字符串
你既省吃俭用又省吃俭用
所以你有:hashedpassword=hashingfunction(password+salt)
尝试登录时:
您可以输入登录名和密码
通过登录,您可以检索hash和base中的salt
你已经有了hashingfunction
所以您可以处理hashingfunction(密码由用户输入+salt)
将结果与hashedpassword进行比较,如果相同,则记录用户
将salt放在散列密码旁边并不会降低安全性:salt的目标是防止使用rainbowtable
如果有人闯入你的数据库,他可能会瞄准你用户的email+密码,因为事实上大多数人在很多不同的地方重复使用相同的密码和email。
现在,由于哈希函数是不可逆的,攻击者唯一能做的就是尝试猜测密码并创建一个词汇:
前任:
如果hash(guessed\u password)在您的数据库中,则他知道此(这些)用户的密码是guessed\u password。
他可以生成一个包含数十亿个猜测的密码的字典,由于很多用户不使用真正的强密码,他很有可能在字典中找到大量的散列用户。因此,如果他为“lola80”和“lola79”生成哈希,这些是你的两个用户的密码,他就知道了。
现在,如果您在输入的每个密码中随机添加一个salt,那么对于每个salt,他必须生成一个完整的字典,因为他必须:
给09年有盐的用户ç@他必须生成一个完整的词汇表,每个单词都在09年结束ç@p$'
现在如果他想猜与salt'yu关联的用户b的密码è他必须产生另一个词汇,每个单词都以“yu”结尾è45英尺
基本上,它会减慢猜测用户密码的速度,这取决于你的用户数。
7dl7o3gd3#
在用户表中创建列
Username
以及Hash
以及Salt
用户寄存器1) 听取意见
username
或者password
从您的注册表中的用户。2) 用下面的方法为输入密码创建hash和salt。
rfc2898derivebytes类用于使用rfc2898规范生成哈希,rfc2898规范使用称为pbkdf2(基于密码的密钥派生函数#2)的方法,ietf(internet工程任务组)目前推荐用于新应用程序。
3) 然后储存了这个
Hash
以及Salt
数据库中的用户记录。用户登录
1) 听取意见
username
或者password
从用户在您的登录表单。2) 在
Login_click
从数据库中按用户名获取用户。3) 通行证已存储
Hash
以及Salt
到下面的函数。4) 然后通过验证用户的密码登录。
参考:有效的密码散列