Sig*_*ils 3 c# encryption hash cryptography pbkdf2
我正在尝试通过哈希和盐析在数据库中保存密码来学习密码学,所以我决定尝试使用登录系统来实现这个系统.
我的数据库包括
我正在使用PBKDF2,但似乎这不是一个散列/腌制方法,如果它不是什么呢?
如果是这样,我这样做对吗?
我的钥匙
private const int SALT_SIZE = 64;
private const int KEY_SIZE = 64;
Run Code Online (Sandbox Code Playgroud)
将数据插入数据库
public static void RegisterMe(string _username, string _password, string _email)
{
using (var cn = new SqlConnection(User.strcon))
{
string _sqlins = @"
INSERT INTO
[User]
([Username],[Salt],[Password],[RegDate], [Email])
VALUES
(@Username, @Salt, @Password, CURRENT_TIMESTAMP, @Email)";
var cmd = new SqlCommand(_sqlins, cn);
cn.Open();
using (var deriveBytes = new Rfc2898DeriveBytes(_password, SALT_SIZE))
{
byte[] salt = deriveBytes.Salt;
byte[] key = deriveBytes.GetBytes(KEY_SIZE);
// save salt and key to database
cmd.Parameters.AddWithValue("@Username", _username);
cmd.Parameters.AddWithValue("@Password", key);
cmd.Parameters.AddWithValue("@Salt", salt);
cmd.Parameters.AddWithValue("@Email", _email);
}
cmd.ExecuteNonQuery();
}
}
Run Code Online (Sandbox Code Playgroud)
检查用户是否有效
public bool IsValid(string _email, string _password)
{
using (var cn = new SqlConnection(strcon))
{
byte[] salt = { }, key = { };
string _sql = @"
SELECT
SALT,
[Password],
UserID
FROM
[User]
WHERE [Email] = @email";
SqlCommand cmd = new SqlCommand(_sql, cn);
cmd.Parameters.AddWithValue("@email", _email);
cn.Open();
SqlDataReader reader = cmd.ExecuteReader();
if (reader.Read())
{
salt = reader.GetSqlBytes(0).Value;
key = reader.GetSqlBytes(1).Value;
reader.Dispose();
cmd.Dispose();
using (var deriveBytes = new Rfc2898DeriveBytes(_password, salt))
{
byte[] newKey = deriveBytes.GetBytes(KEY_SIZE); // derive a 20-byte key
return newKey.SequenceEqual(key);
}
}
else
{
reader.Dispose();
cmd.Dispose();
return false;
}
}
}
Run Code Online (Sandbox Code Playgroud)
我的系统工作,它将数据作为字节设置到数据库中,如果用户输入正确的密码,则返回true.但这是正确的方法吗?这甚至是哈希/盐渍吗?
你基本上是朝着正确的方向前进,但我会指出一些需要考虑的事情:
PBKDF2方法的默认迭代次数可能不足,您可能不希望将内容保留为默认值.我建议指定一个至少10K的迭代计数.
另一方面,密钥大小和salt大小由此实现计算,以字节为单位.64字节有点太多了.每个都保持16个字节应该是充足的.不建议超过20个字节,因为它是底层散列函数/ HMAC的最大大小.越过这一点只会给攻击者一个优势(据许多人说,这是PBKDF2中的一个设计错误).您当然可以将varbinary的大小设置为更高的值以允许将来升级.
建议您使用salt和散列密码保存协议号.这样做可以让您在以后的日期和每个条目升级方案,此时用户可以重置他/她的密码.
小点; MSDN未指定何时生成salt.我会检查盐的随机性(检查它是否每次都不同)并且在调用之后只询问盐getBytes
以确保盐确实是随机的,即使实施改变了.否则使用加密安全随机数生成器自己生成它.